Castle Windsor解析带有开放泛型和接口的数组

4
我希望使用Castle Windsor解决以下问题:
IEnumerable<Definition<IEntity>>

目前我只得到了一个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>>));

你能添加你的注册码吗? - Marwijn
你为 Definition<> 接口编写的实现代码在哪里? - Matt Whetton
1个回答

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类型。关于协变和逆变的更多信息,请参见此处: 泛型中的协变和逆变 因此,我建议您引入以下接口:
public interface IDefinition<out TEntity>
    where TEntity : IEntity
{
}

请注意使用了 out 关键字,将接口标记为协变。然后从该接口派生你的 Definition<TEntity> 类:
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方法。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接