Ric*_*ews 5 c# dependency-injection castle-windsor ioc-container
我们有一个解决方案,其中有多个项目代表我们的应用程序层.例如
域
数据
逻辑
WebUI中
我们的Castle Windsor容器从我们的Web层引用,然后我们将这些依赖项级联到层.例如...
// In Domain
public interface IFooRepository
{
void DoSomething();
}
// In Data
public class FooRepository : IFooRepository
{
public void DoSomething()
{
// Something is done
}
}
// In Logic
public class MyThingManager
{
private readonly IFooRepository fooRepository;
public MyThingManager(IFooRepository fooRepository)
{
this.fooRepository = fooRepository;
}
public void AMethod()
{
this.fooRepository.DoSomething();
}
}
// In Web
// in some controller....
var newManager = new MyThingManager(WindsorContainer.Resolve<IFooRepository>());
newManager.DoSomething();
Run Code Online (Sandbox Code Playgroud)
这很好用,直到我们的经理有很多成员有自己的依赖.当这种情况发生时,我们最终解决了管理者的依赖性和他们的依赖性,并将其从Web层级联起来.这个结果是一些相当大的构造函数.
是否有更优雅的方式,例如让经理的内部组件解决它自己的依赖性而无法访问容器?
请记住,只有Web层可以访问容器(以防止循环项目依赖),因此只有Web层可以激活WindsorContainer.Resolve()逻辑层不能这样才能级联依赖性的唯一方法容器帮助是在Web层中解决它,然后使用它的界面将其传递给链.
简短的回答是,每当你看到.Resolve<T>你可能做错了.正如@Steven所提到的,您希望使用Windsor的内置功能为您提供构造函数注入(和/或属性注入).这意味着WindsorContainer需要知道对象图根的对象.
在您的情况下,您将走到对象树(从MyThingyManager)到达根对象.例如,在ASP.NET MVC应用程序中,这将是包含被调用操作的控制器.对于MVC3案例,您将使用DependencyResolver启动所有依赖项的注入.
此外,我发现过去与Windsor一起使用的是每个组件(组件)具有不同的安装程序.然后在托管应用程序的进程的基础上注册这些安装程序.
因此,在每个组件中,您将拥有如下安装程序:
public class Installer : IWindsorInstaller
{
public void Install(Castle.Windsor.IWindsorContainer container, Castle.MicroKernel.SubSystems.Configuration.IConfigurationStore store)
{
container.Register(
Component.For<IMyThingManager>().ImplementedBy<MyThingManager>(),
Component.For<IFooRepository>().ImplementedBy<FooRepository>()
);
}
}
Run Code Online (Sandbox Code Playgroud)
然后在Global.asax.cs Application_Start中你会得到类似的东西:
var container = new WindsorContainer();
container.Install(FromAssembly.This());
container.Install(FromAssembly.Containing(typeof(ComponentThatContains.MyThingManager.Installer)));
Run Code Online (Sandbox Code Playgroud)
这为您提供了一种方法来管理整个对象图中的所有依赖关系,并通过构造函数注入来解决.希望这可以帮助.