当你没有对容器的引用时,是否有可能让Castle Windsor解决属性依赖性问题?

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层中解决它,然后使用它的界面将其传递给链.

Dav*_*yon 6

简短的回答是,每当你看到.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)

这为您提供了一种方法来管理整个对象图中的所有依赖关系,并通过构造函数注入来解决.希望这可以帮助.