使用Castle.Windsor在集合中注册相同类型会产生异常

时间:2014-05-21 06:42:36

标签: c# dependency-injection castle-windsor

我正在尝试使用Castle.Windsor对位于列表中的组件进行DI。

我有三种类型(在本例中为Boats),它们都从一个接口(IBoat)继承,我随机生成这些类型的10个实例。当它添加不同类型时,一切都很好,但是当添加已经存在于集合中的相同类型时,它会出现以下错误:

Component MarinaTest.SailBoat could not be registered. 
There is already a component with that name. Did you want to modify the existing 
component instead? If not, make sure you specify a unique name.

其中包含集合的父类如下所示:

public class BoatsAtSea
{
    public List<IBoat> BoatsList { get; set; } 
    public BoatsAtSea(List<IBoat> boatsAtSea)
    {
        BoatsList = boatsAtSea;
    }
}

Castle I的代码使用:

Type[] types = {typeof(SailBoat), typeof(FisherBoat), typeof(YachtBoat)};


        var basContainer = new WindsorContainer();
        basContainer.Kernel.Resolver.AddSubResolver(new ListResolver(basContainer.Kernel));
        basContainer.Register(Component.For<BoatsAtSea>());

        // Generate 10 random boats
        for (int i = 0; i < 10; i++)
        {
            basContainer.Register(Component.For<IBoat>().LifestyleTransient().ImplementedBy(types[new Random().Next(3)])
            .DependsOn(Dependency.OnValue("Name", "BT"+ i)));
        }

        BoatsAtSea boats = basContainer.Resolve<BoatsAtSea>();

我尝试了几种选择,但我无法弄清楚是什么问题。 感谢。

3 个答案:

答案 0 :(得分:1)

您应该注册一次实施:

container.Register(Classes.FromThisAssembly()
                          .IncludeNonPublicTypes()
                          .BasedOn<IBoat>()
                          .WithService.FromInterface()
                          .LifestyleTransient());

然后创建一个获取随机IBoat实现的方法:

private IEnumerable<IBoat> GetRandomBoatImplementation(IKernel container, int count)
{
    for (int i = 0; i < count; i++)
    {
        yield return container.ResolveAll<IBoat>()
                              .OrderBy(item => Guid.NewGuid())
                              .FirstOrDefault();
    }
}

使用此方法创建列表。这使得ListResolver变得多余,因为我们自己注册了这个类型:

container.Register(Component.For<List<IBoat>>()
                            .UsingFactoryMethod(input => GetRandomBoatImplementation(input, 10).ToList()));

答案 1 :(得分:0)

您不能多次明确注册相同的组件(类型)。

根据你的代码,for循环导致不止一次注册相同的类型(从你的类型数组中选择)

答案 2 :(得分:0)

如果使用命名:

命名组件,则可以执行此操作
basContainer.Register(Component.For<IBoat>()
    .LifestyleTransient()
    .ImplementedBy(types[new Random().Next(3)])
    .Named("BT"+i)
    .DependsOn(Dependency.OnValue("Name", "BT"+ i)));

你还得改变:

BoatsAtSea(List<IBoat> boatsAtSea)

为:

BoatsAtSea(IList<IBoat> boatsAtSea)

亲切的问候,

Marwijn。