2012-04-11 20 views
5

我们有一个代表我们应用层的多个项目的解决方案。 例如当你没有对容器的引用时,是否有可能让Castle Windsor解决属性依赖问题?

数据

逻辑

WebUI中

我们的温莎城堡容器从我们的网络层引用然后我们通过我们的层高达级联这些依赖关系。例如...

// 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(); 

,这很好地工作,直到我们的管理者有很多有自己的依赖关系的成员。发生这种情况时,我们最终会解决管理员依赖关系及其依赖性问题,并将其从Web层层叠起来。这个结果是一些相当大的构造函数。

是否有更优雅的方式,例如让管理器的内部组件解决它自己的依赖关系而无需访问容器?

请记住,只有web层有权访问容器(以防止循环项目依赖),所以只有web层可以激活WindsorContainer.Resolve()逻辑层不能这样才能级联的唯一方法没有容器协助的依赖是在Web层中解决它,然后使用它的接口将它传递给链。

+2

“我们最终解决了管理者依赖关系及其依赖关系的瑕疵,并将它们从网络层级层叠起来”。我不明白这一点。当你使用构造函数注入并让容器自动在类型的构造函数中注入依赖关系时,应该没有问题。显示更多的代码可视化这个问题可能会有所帮助。 – Steven 2012-04-11 11:24:48

回答

6

简短的回答是,只要你看到.Resolve<T>你可能是doing it wrong。正如@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>() 
       ); 
     } 
} 

然后在Global.asax.cs中的Application_Start你会碰到这样的:

var container = new WindsorContainer(); 
container.Install(FromAssembly.This()); 
container.Install(FromAssembly.Containing(typeof(ComponentThatContains.MyThingManager.Installer))); 

这给你一个方法管理整个对象图中的所有依赖关系并通过构造器注入来解决。 希望这有助于。

+0

感谢你们对我们如何做IOC的全面重新思考,现在它像魔术一样工作:D – 2012-04-13 19:43:48

+0

很高兴听到,很高兴我能帮上忙。 – 2012-04-13 22:29:08

相关问题