.net Castle Windsor将命名组件映射到特定属性
以下场景: 我们使用fluentapi注册一个程序集中的所有组件,并使用命名键注册两个组件tyepof(A)。另一个具有两个属性TypeA的类B应该注入命名组件 样本:.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; } } //
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,这实际上是我想要输入的内容。;)修好了。