Castle Windsor:如何在实现特定接口时注册多个类型
本文关键字:接口 注册 类型 Windsor 实现 Castle | 更新日期: 2023-09-27 17:59:31
更新
我有以下类/接口:
public interface IFoo
{
(...)
}
public interface IFoo<T> : IFoo
{
(...)
}
public abstract BaseFoo<T> : IFoo<T>
{
(...)
}
public Bar : BaseFoo<ConcreteType1>
{
(...)
}
public Baz : BaseFoo<ConcreteType2>
{
(...)
}
使用Castle Windsor,如何将Bar和Baz类型注册为实现IFoo?
我已经尝试了一些失败的东西,比如:
Register(Types.FromAssembly(typeof (IFoo).Assembly)
.BasedOn<IFoo>()
.WithService
.Select(new List<Type> { typeof(IFoo)})
.Configure(x => x.LifeStyle.Is(LifestyleType.Singleton)));
EDIT:注释中声明的异常告诉正在尝试解决抽象类BaseFoo
。这是因为您使用Types
来选择所有组件,甚至是抽象类。避免这种情况的一个简单方法是使用不存在此问题的Classes
。文件说明:
我应该使用类还是类型?
有两种方法可以开始公约登记。其中之一是使用Classes静态类,就像上面的例子一样。其次是使用Types静态类。他们两者都暴露了完全相同的方法。它们之间的区别在于,类型将允许您注册所有使用默认设置,所有公共)类型,即类、接口、结构、委托和枚举。上的类另一方面,预筛选类型以仅考虑非抽象类。大多数情况下,类是您将要使用的,但类型可以在某些高级场景中非常有用,例如基于接口的类型化工厂。
这段代码看起来是正确的——事实上,我用三个不同的WithService
调用(Base-AllInterfaces和Select)进行了尝试,每一个都成功了。我认为这可能是你选择的第一部分可能不正确:Types.FromAssembly(typeof (IFoo).Assembly)
我没有找到任何方法来获得castle在尝试使用fluent注册时考虑的内容的列表,但您可以使用Configure
来记录考虑的组件的名称:
c.Register(Classes.FromAssemblyInThisApplication()
.BasedOn<IFoo>()
.Configure(x => Console.WriteLine(x.Implementation.Name)) // classes names
.WithService.Select(new Type[] {typeof(IFoo)})
.Configure(x => x.LifeStyle.Is(LifestyleType.Singleton)));
因此,请尝试检查您是否使用了正确的程序集,或者您的类是否对容器可见
编辑
此代码有效:
public interface IFoo
{
}
public interface IFoo<T> : IFoo
{
}
public abstract class BaseFoo<T> : IFoo<T>
{
}
public class Bar : BaseFoo<Bar>
{
}
public class Baz : BaseFoo<Baz>
{
}
// main
var c = new Castle.Windsor.WindsorContainer();
c.Register(Classes.FromAssemblyInThisApplication()
.BasedOn<IFoo>()
.Configure(x => Console.WriteLine(x.Implementation.Name))
.WithService.Select(new Type[] {typeof(IFoo)})
.Configure(x => x.LifeStyle.Is(LifestyleType.Singleton)));
var all = c.ResolveAll<IFoo>(); // 2 components found