我们正在评估C#项目的IoC容器,Unity和CaSTLe.Windsor都脱颖而出。我对Unity感兴趣的一件事(NInject和StructureMap也可以做到这一点)是,很明显如何构造它们的类型不必在IoC容器中注册。
有没有办法在CaSTLe.Windsor中做到这一点?我对CaSTLe.Windsor说不对吗?是否出于设计原因而故意不执行此操作,或者是疏忽大意,还是只是认为它不重要或没有用?
我知道在温莎(Windsor)中的container.Register(AllTypes...
,但这不是一回事。它不是完全自动的,而且范围很广。
为了说明这一点,这是两个通过Unity和CaSTLe.Windsor执行相同操作的NUnit测试。 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());
}
}
}
最佳答案
温莎不开箱即用,这是一个有意的决定。有关更多详细信息,请参见this answer。
但是,可以通过根据需要延迟注册未注册的组件来真正轻松地扩展更高版本以支持此方案。
您将必须实现ILazyComponentLoader
接口(interface),该接口(interface)将占用5行代码。有关示例,请参见here。
尽管我在2018年的建议与2009年的建议相同-除非在非常的特定场景中有非常的特定场景,否则不要这样做
关于.net - Can CaSTLe.Windsor可以自动解析混凝土类型吗,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/1955579/