具有开放通用和接口的 Castle Windsor 解析数组
Posted
技术标签:
【中文标题】具有开放通用和接口的 Castle Windsor 解析数组【英文标题】:Castle windsor resolve array with open generic and interface 【发布时间】:2013-09-04 13:50:43 【问题描述】:我想用温莎城堡解决以下问题:
IEnumerable<Definition<IEntity>>
目前我只得到一个带有 1 个对象的 IEnumerable,它与 IEntity 的第一个实现相匹配。
我想要一个数组
Definition<Entity1>, Definition<Entity2>, ...
我觉得需要一个子解析器,但我不知道从哪里开始。
更新
var container = new WindsorContainer();
container.Kernel.Resolver.AddSubResolver(
new CollectionResolver(container.Kernel, true));
container.Register(Component.For(typeof (Definition<>)));
var binDir = HostingEnvironment.MapPath("~/bin");
var assemblyFilter = new AssemblyFilter(binDir);
container.Register(Types.FromAssemblyInDirectory(assemblyFilter)
.BasedOn<IEntity>()
.Unless(t => t.IsAbstract || t.IsInterface)
.WithServiceAllInterfaces()
.LifestyleTransient());
// This doesn't work!
var items = container.Resolve(typeof(IEnumerable<Definition<IEntity>>));
【问题讨论】:
您可以添加您的注册码吗? 定义的实现在哪里? 【参考方案1】:首先,我认为您应该稍微改进一下您的设计。我不知道实际情况,但我相信您的意图如下:
public interface IEntity
public class Entity1 : IEntity
public class Entity2 : IEntity
public abstract class Definition<TEntity>
where TEntity : IEntity
public class Entity1Definition : Definition<Entity1>
public class Entity2Definition : Definition<Entity2>
使用这种设计,您会遇到以下代码无效的问题:
Definition<IEntity> definition = new Entity1Definition();
为了使其工作,您应该为 IEntity 类型引入协变通用接口。更多关于协变和逆变的信息,你可以在这里找到:Covariance and Contravariance in Generics
所以我建议你引入以下接口:
public interface IDefinition<out TEntity>
where TEntity : IEntity
注意将接口标记为协变的 out 关键字。然后从这个接口导出你的Definition
public abstract class Definition<TEntity> : IDefinition<TEntity>
where TEntity : IEntity
现在,当我们以这种方式设置设计后,剩下的就很容易了。我们可以像这样注册组件:
WindsorContainer container = new WindsorContainer();
container.Kernel.Resolver.AddSubResolver(
new CollectionResolver(container.Kernel, true));
container.Register(Types.FromThisAssembly()
.BasedOn(typeof(IDefinition<>))
.Unless(t => t.IsAbstract || t.IsInterface)
.WithServices(typeof(IDefinition<IEntity>))
.LifestyleTransient());
然后解决它们:
var items = container.ResolveAll(typeof(IDefinition<IEntity>));
注意,要解析 Windsor 中注册服务的所有实例,您应该调用 ResolveAll 方法。
【讨论】:
以上是关于具有开放通用和接口的 Castle Windsor 解析数组的主要内容,如果未能解决你的问题,请参考以下文章
Castle Windsor 学习-----Installer的几种安装方式
castle windsor学习-------Container Events 容器的事件
Castle.Windsor依赖注入的高级应用_Castle.Windsor.3.1.0
Castle Windsor 3 + Fluent NHibernate + Castle.NHibernate.Integration