.net Castle Windsor将命名组件映射到特定属性

.net Castle Windsor将命名组件映射到特定属性,.net,castle-windsor,ioc-container,.net,Castle Windsor,Ioc Container,以下场景: 我们使用fluentapi注册一个程序集中的所有组件,并使用命名键注册两个组件tyepof(A)。另一个具有两个属性TypeA的类B应该注入命名组件 样本: public class A : IA {} public class B : IB { [Named("first")] public IA First { get; set; } [Named("second")] public IA Second { get; set; } } //

以下场景:

我们使用fluentapi注册一个程序集中的所有组件,并使用命名键注册两个组件tyepof(A)。另一个具有两个属性TypeA的类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
公共类A:IA{}
B级:IB
{
[命名(“第一”)]
公共IA第一个{get;set;}
[已命名(“第二名”)]
公共IA第二个{get;set;}
}
// ...
container.Register(Component.For().Instance(新的A(value1)).Named(“first”);
container.Register(Component.For().Instance(新的A(value2)).Named(“second”);
// ...
var b=container.Resolve();//使用命名属性将A的命名实例注入B

这是否可以通过像Named这样的属性实现,或者仅通过Xml配置实现?

在Windsor中实现这一点的标准方法是使用。在您的示例中,当您注册
B
时,您会这样做:

container.Register(Component.For<IB>().ImplementedBy<B>()
                     .ServiceOverrides(new {First = "first", Second = "second"}));
container.Register(Component.For().ImplementedBy())
.ServiceOverrides(新的{First=“First”,Second=“Second”});
(还有其他表达方式,请检查链接的文档)


您建议使用名为的
属性会以不相关的关注点污染代码(
B
不应该关心
a
s被注入了什么)

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

container.Register
(
用于()的组件
.实例(新A(值1))
.命名为(“第一”),
用于()的组件
.实例(新A(值2))
.名为(“第二”),
用于()的组件
.由()实施
德彭森先生
(
Dependency.OnComponent(名称为(B.First),“First”),
Dependency.OnComponent(名称(B.Second),“Second”)
)      
)
Dependency.OnComponent
有许多重写,但在本例中,第一个参数是属性名,第二个参数是组件名


有关更多文档,请参阅。

我知道了。是的,这是有意义的,我喜欢非侵入性方法,尽管您有匿名类型的属性输入错误的风险。我想这会引发一个例外,因此注册的单元测试将涵盖这一点?@Rene Schulte:使用
命名的
属性方法,您可能会错误输入某些组件的名称。大多数(全部?)IoC容器都有一个缺点:会丢失一些静态类型检查。@Rene Schulte:另外,可以使用表达式而不是字符串来表示属性,请注意ServiceOverrides现在已经过时了。使用DependsOn(Dependency.OnComponent())代替。顺便说一句
B
应该被
IA
注入,而不是具体的
A
True,这实际上是我想要输入的内容。;)修好了。