c# - 温莎城堡 : Force resolver to use specified constructor

标签 c# .net dependency-injection castle-windsor ioc-container

例子如下:

interface IComponentA {};

class ComponentA : IComponentA { };

interface IComponentB { };

class ComponentB : IComponentB { };

interface IComponentC { };

class ComponentC : IComponentC
{
    public ComponentC(IComponentA a)
    {
        Console.WriteLine("Constructor A"); 
    }

    public ComponentC(IComponentB b) 
    {
        Console.WriteLine("Constructor B");
    }
};

所有这些组件都注册在 CaSTLe Windsor 容器中。

但是 ComponentC 类有 2 个重载的构造函数。当 ComponentC 被激活时,它们中的任何一个都可以使用。

我需要使用 ComponentC(IComponentB b) 构造函数。

暂时我使用 UsingFactoryMethod() 方法来解决这个问题:

container
    .Register(Component
        .For<IComponentA>()
        .ImplementedBy<ComponentA>())
    .Register(Component
        .For<IComponentB>()
        .ImplementedBy<ComponentB>())
    .Register(Component
        .For<IComponentC>()
        .UsingFactoryMethod(() => new ComponentC(
            container.Resolve<IComponentB>())));

它有效,但可能温莎城堡提供了一些更好的方法来做到这一点?

非常感谢任何帮助。

谢谢。

最佳答案

Windsor 不支持这种情况,因为它打破了它(和大多数容器)基于以下不成文的假设之一:“所有构造函数都是平等的”。

这意味着,无论选择哪个构造函数,组件的行为都不应存在功能差异。在所有条件都相同的情况下,组件具有的依赖项越多,它拥有的功能就越多,这就是为什么 Windsor 会倾向于首先选择更贪婪的构造函数,但如果像你这样,我会说两种情况中的任何一种正在发生:

  • 您的组件实际上可能是伪装成一个的两个组件。在这种情况下,您可能会想要拆分它。
  • 您的组件实际上确实使用它所具有的两个依赖项进行操作,因此它应该有一个接受它们的构造函数。

我见过的另一种情况是这样的:

public class Foo
{
   public Foo(ISession session){/*code*/}
   public Foo(ISessionFactory factory):this(factory.OpenSession()){}
}

虽然乍一看这似乎是个聪明的主意,但充其量它是多余的、令人困惑的和不必要的。如果你的案例看起来像这个,我会删除第二个构造函数。

关于c# - 温莎城堡 : Force resolver to use specified constructor,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7926686/

相关文章:

.net - 单击后如何保持打开 rad 菜单?

java - 在 Spring @Value 注释中省略美元占位符

c# - IoC 容器中的命名服务——一个坏主意?

C#如何判断一个对象是否为多维数组

c# - 在 64 位环境中将指定的 NUnit 测试作为 32 位进程运行

c# - 在 ASP.NET 中创建验证码的代码?

.net - Ruby WIN32OLE 可以访问 .NET .dll 的要求

java - 将依赖项注入(inject)普通的旧 Tomcat HTTP servlet

c# - 如何编写 Nhibernate 查询

c# - 在 WPF 中,OnLostKeyboardFocus 是否保证在 OnGotKeyboardFocus 之后被调用?