【问题标题】:Is it possible to have Castle Windsor resolve property dependancies when you dont have a reference to the container?当您没有对容器的引用时,是否可以让 Castle Windsor 解决属性依赖关系?
【发布时间】:2012-04-23 16:36:35
【问题描述】:

我们有一个解决方案,其中包含多个代表我们应用程序层的项目。 例如

域名

数据

逻辑

网页界面

我们的 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();

这很有效,直到我们的经理有很多成员都有自己的依赖关系。当这种情况发生时,我们最终解决了管理器的依赖关系及其依赖关系,并将它们从 Web 层级联起来。这个结果是一些相当大的构造函数。

是否有更优雅的方式,例如让管理器的内部组件在无需访问容器的情况下解决其自身的依赖关系?

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

【问题讨论】:

  • “我们最终解决了管理器的依赖关系及其依赖关系的依赖关系,并将它们从 Web 层级联起来”。我不明白这一点。当你使用构造函数注入,让容器自动将依赖注入到一个类型的构造函数中,应该完全没有问题。显示更多可视化此问题的代码可能会有所帮助。

标签: c# dependency-injection castle-windsor ioc-container


【解决方案1】:

简短的回答是,每当您看到.Resolve&lt;T&gt; 时,您可能就是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)));

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

【讨论】:

  • 感谢您,它开启了对我们如何进行 IOC 的全面重新思考,现在它就像魔术一样工作:D
  • 很高兴听到,很高兴我能帮上忙。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多