Castle Windsor地图命名为特定属性的组件

时间:2011-02-17 14:46:20

标签: .net castle-windsor ioc-container

以下情景:

我们使用Fluent API注册程序集中的所有组件,并使用命名键注册两个组件tyepof(A)。另一个具有两个属性typeof(A)的B类应该获得注入的命名组件。

样品:

public class A : IA {}

public class B : IB
{
    [Named("first")]
    public IA First { get; set; }

    [Named("second")]
    public IA Second { get; set; }
}

// ...

container.Register(Component.For<IA>().Instance(new A(value1)).Named("first"));
container.Register(Component.For<IA>().Instance(new A(value2)).Named("second"));

// ...
var b = container.Resolve<IB>(); // named instances of A get injected to B using the Named attribute

是否可以使用Named等属性或仅使用Xml Config?

2 个答案:

答案 0 :(得分:4)

在Windsor中执行此操作的标准方法是使用service overrides。在您的示例中,当您注册B时,您可以这样做:

container.Register(Component.For<IB>().ImplementedBy<B>()
                     .ServiceOverrides(new {First = "first", Second = "second"}));

(还有其他表达方式,请查看链接的文档)

建议使用Named属性污染具有不相关问题的代码(B不应该关心A被注入的内容。

答案 1 :(得分:1)

以下是使用DependsOn并合并nameof表达式(在C#6.0中引入)来解决此问题的方法:

container.Register
(
    Component.For<IA>()
        .Instance(new A(value1))
        .Named("first"),
    Component.For<IA>()
         .Instance(new  A(value2))
         .Named("second"),
    Component.For<IB>()
          .ImplementedBy<B>()
          .DependsOn
          (
              Dependency.OnComponent(nameof(B.First), "first"),
              Dependency.OnComponent(nameof(B.Second), "second")
          )      
)

Dependency.OnComponent有许多覆盖,但在这种情况下,第一个参数是属性名称,第二个参数是组件名称。

有关更多文档,请参阅here