可以Castle.Windsor自动解决具体类型

Ant*_*ony 6 .net castle-windsor ioc-container inversion-of-control unity-container

我们正在为C#项目评估IoC容器,Unity和Castle.Windsor都很突出.我喜欢Unity的一件事(NInject和StructureMap也这样做)是明显如何构造它们的类型不必在IoC容器中注册.

有没有办法在Castle.Windsor做到这一点?我对Castle很公平.温莎要说它不这样做吗?有没有设计理由故意不这样做,或者是疏忽,还是只是没有被视为重要或有用?

我知道container.Register(AllTypes...在温莎,但这不是一回事.它不是完全自动化的,而且非常广泛.

为了说明这一点,这里有两个NUnit测试通过Unity和Castle.Windsor做同样的事情.Castle.Windsor失败了.:

namespace SimpleIocDemo
{
    using NUnit.Framework;
    using Castle.Windsor;
    using Microsoft.Practices.Unity;

    public interface ISomeService
    {
        string DoSomething();
    }

    public class ServiceImplementation : ISomeService
    {
        public string DoSomething()
        {
            return "Hello";
        }
    }

    public class RootObject
    {
        public ISomeService SomeService { get; private set; }

        public RootObject(ISomeService service)
        {
            SomeService = service;
        }
    }

    [TestFixture]
    public class IocTests
    {
        [Test]
        public void UnityResolveTest()
        {
            UnityContainer container = new UnityContainer();
            container.RegisterType<ISomeService, ServiceImplementation>();
            // Root object needs no registration in Unity
            RootObject rootObject = container.Resolve<RootObject>();
            Assert.AreEqual("Hello", rootObject.SomeService.DoSomething());
        }

        [Test]
        public void WindsorResolveTest()
        {
            WindsorContainer container = new WindsorContainer();
            container.AddComponent<ISomeService, ServiceImplementation>();

            // fails with exception "Castle.MicroKernel.ComponentNotFoundException: 
            // No component for supporting the service SimpleIocDemo.RootObject was found"
            // I could add
            // container.AddComponent<RootObject>();
            // but that approach does not scale
            RootObject rootObject = container.Resolve<RootObject>();
            Assert.AreEqual("Hello", rootObject.SomeService.DoSomething());
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Krz*_*mic 6

温莎并不支持开箱即用,这是一个深思熟虑的决定.有关详细信息,请参阅此答案.

但是,通过懒惰地注册未注册的组件,可以非常容易地扩展更高版本以支持这种情况.你必须实现ILazyComponentLoader接口,这将占用5行代码.请看这里的例子.

尽管我在2018年的建议是,因为它是在2009年一样的-不这样做,除非在非常,你有一个特定的场景非常充分的理由选择此方法在备选方案