我有2个组件(AWriter和BWriter),两者都实现IWriter接口。我有2个组件(accomponent和BComponent),两者都实现接口iccomponent,都依赖于IWriter。但是在一个组件中,我想告诉Windsor给我一个writer的实例,在BComponent中,我想告诉Windsor给我一个BWriter的实例。怎么做呢?
代码如下:
public interface IWriter
{
void Write();
}
public class AWriter : IWriter
{
public void Write()
{
Console.Write("A writer");
}
}
public class BWriter : IWriter
{
public void Write()
{
Console.Write("B writer");
}
}
public interface IComponent
{
void Do();
}
public class AComponent : IComponent
{
IWriter writer;
public AComponent(IWriter writer)
{
this.writer = writer;
}
public void Do()
{
writer.Write();
}
}
public class BComponent : IComponent
{
IWriter writer;
public BComponent(IWriter writer)
{
this.writer = writer;
}
public void Do()
{
writer.Write();
}
}
注意:这只是一个简化的问题,把AWriter放在component中,BWriter放在BComponent中作为依赖不是一个选项。同样,在这个例子中,a组件和b组件看起来可能是一样的,但这不是真实的情况。在实际情况中,我有更多的依赖项和组件,我不想为此烦恼。
那么,有没有一种方法可以通过某些属性指定Castle应该给我哪个实现?
您希望使用命名组件和服务覆盖。查看Windsor的文档获取帮助:http://docs.castleproject.org/Windsor.Registering-components-one-by-one.ashx
使用流畅注册,你可以这样做:
container.Register(Component.For<IComponent>()
.ImplementedBy<AWriter>().Named("AWriter"),
Component.For<IComponent>()
.ImplementedBy<BWriter>().Named("BWriter"));
:
container.Register(Component.For<IComponent>()
.ImplementedBy<AComponent>()
.ServiceOverrides(
ServiceOverride.ForKey("writer").Eq("AWriter"));
container.Register(Component.For<IComponent>()
.ImplementedBy<BComponent>()
.ServiceOverrides(
ServiceOverride.ForKey("writer").Eq("BWriter"));
当然,这将导致iccomponent的两个注册,但是如果你需要注入特定的实例,你可以命名它们,并使用服务覆盖将每个实现注入到依赖结构中的适当位置。