简体   繁体   English

温莎城堡:如何注入所有工厂的藏品?

[英]Castle Windsor: How to inject the collection of all factories?

Using Castle Windsor, I want to get the collection of all factories that implement a particular interface. 我想使用Castle Windsor获得实现特定接口的所有工厂的集合。

Say you have the following type hierarchy: 假设您具有以下类型层次结构:

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

using TypedFactoryFacility I am able to inject a Func<IAnimal> that acts as a factory to create animal instances (with transient life cycle). 使用TypedFactoryFacility我可以注入一个Func<IAnimal> ,它充当创建动物实例(具有瞬态生命周期)的工厂 I can also use CollectionResolver to resolve a collection of animals with singleton life cycles. 我还可以使用CollectionResolver来解析具有单个生命周期的动物的集合 But in the following example, it seems that you cannot combine the effects of TypedFactoryFacility and CollectionResolver to resolve a collection of factories. 但是在下面的示例中,您似乎无法结合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>();
    }
}

This results in the following error: 这将导致以下错误:

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

You have to do these steps : 您必须执行以下步骤:

  1. Register an interface as factory with the lifetime that suits your needs. 将接口注册为工厂,并选择适合您需求的使用寿命。 The interface has no impleentation because it is castle typed factory facility. 该接口没有实现,因为它是城堡类型的工厂设施。 I register such providers as singletons : 我将此类提供者注册为singletons:

    Component.For().AsFactory() Component.For()。AsFactory()

I intentionally name it provider because it does not create new intances by some logic but provides you the already registered instances. 我故意将其命名为provider,因为它不会通过某些逻辑创建新实例,但会为您提供已注册的实例。

  1. The interface must look like this : 接口必须如下所示:

    public interface IAnimalFactoryProvider { IEnumerable<IAnimalFactory> GetAllAnimalFactories(); 公共接口IAnimalFactoryProvider {IEnumerable <IAnimalFactory> GetAllAnimalFactories(); void Release(IAnimalFactory animalFactory); void Release(IAnimalFactory animalFactory); } }

  2. Then you put IModuleModelInitializerProvider in a ctor that you want it injected and then get all hte instances through the method GetAllAnimalFactories(). 然后,将IModuleModelInitializerProvider放入要注入的ctor中,然后通过方法GetAllAnimalFactories()获取所有hte实例。

  3. Then depending on your IAnimal factories you may release them after use or if they are singletons too you can just leave them and Castle will dispose them when your application quits. 然后,根据您的IAnimal工厂,您可以在使用后释放它们,或者如果它们也是单例的,您也可以离开它们,Castle会在您的应用程序退出时对其进行处理。

Another approach - typed factory as delegate is described here , here , here , here and here 这里这里这里这里这里描述另一个方法类型的工厂作为委托

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM