问题
Following scenario:
We use the Fluent API to register all components in an assembly and two components tyepof(A) with named keys. Another class B with two properties typeof(A) should get the named components injected.
Sample:
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
Is this possible with an attribute like Named or only with the Xml Config?
回答1:
The standard way to do this in Windsor is using service overrides. In your example, when you register B
you'd do it like this:
container.Register(Component.For<IB>().ImplementedBy<B>()
.ServiceOverrides(new {First = "first", Second = "second"}));
(there are other ways to express this, check the linked docs)
Using a Named
attribute as you propose pollutes the code with unrelated concerns (B
should not care about what A
s get injected)
回答2:
Here's how you would solve this problem using DependsOn
and incorporating the nameof
expression (introduced in 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
has many overrides, but in this case the first parameter is the property name, and the second parameter is the component name.
See here for more documentation.
来源:https://stackoverflow.com/questions/5030431/castle-windsor-map-named-component-to-specific-property