温莎城堡:如何注入所有工厂的集合?

时间:2015-01-10 00:14:44

标签: c# dependency-injection castle-windsor

使用Castle Windsor,我想获得实现特定界面的所有工厂的集合。

假设您有以下类型层次结构:

public interface IAnimal { }
public class Cat : IAnimal { }
public class Dog : IAnimal { }

使用TypedFactoryFacility我可以注入一个充当工厂Func<IAnimal>来创建动物实例(具有瞬态生命周期)。我也可以使用CollectionResolver来解决具有单身生命周期的动物的集合。但在下面的示例中,您似乎无法将TypedFactoryFacilityCollectionResolver的效果结合起来来解析工厂集合。

public class Zoo
{
    public Zoo(IEnumerable<Func<IAnimal>> animalFactories)
    {
        foreach (Func<IAnimal> factory in animalFactories)
        {
            IAnimal animal = factory();
            Console.WriteLine(animal.GetType());
        }
    }
}

class Test
{
    static void Main(string[] args)
    {
        IWindsorContainer container = new WindsorContainer();
        container.AddFacility<TypedFactoryFacility>();
        container.Kernel.Resolver.AddSubResolver(new CollectionResolver(container.Kernel));

        container.Register(Component.For<IAnimal>().ImplementedBy<Cat>().LifestyleTransient());
        container.Register(Component.For<IAnimal>().ImplementedBy<Dog>().LifestyleTransient());
        container.Register(Component.For<Zoo>());

        container.ResolveAll<IAnimal>();
        container.Resolve<Zoo>();
    }
}

这会导致以下错误:

Component Zoo has a dependency on System.Collections.Generic.IEnumerable`1[System.Func`1[IAnimal]], which could not be resolved.

1 个答案:

答案 0 :(得分:2)

您必须执行以下步骤:

  1. 在工厂注册一个符合您需求的生命周期。该接口没有实现,因为它是castle typed factory facility.我将这些提供者注册为单身:

    Component.For()。AsFactory()

  2. 我故意将其命名为提供者,因为它不会通过某些逻辑创建新的内容,但会为您提供已注册的实例。

    1. 界面必须如下所示:

      公共接口IAnimalFactoryProvider     {         IEnumerable的&LT; IAnimalFactory&GT; GetAllAnimalFactories();         void Release(IAnimalFactory animalFactory);     }

    2. 然后将IModuleModelInitializerProvider放入要注入的ctor中,然后通过方法GetAllAnimalFactories()获取所有hte实例。

    3. 然后根据你的IAnimal工厂,你可以在使用后释放它们,或者如果它们是单身,你也可以离开它们,Castle会在你的申请退出时处理它们。

    4. 另一种方法 - 类型工厂作为委托被描述为hereherehereherehere