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

本文关键字:工厂 集合 注入 城堡 何注入 | 更新日期: 2023-09-27 18:36:56

使用温莎城堡,我想获取实现特定接口的所有工厂的集合。

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

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. 将接口注册为工厂,其生存期适合您的需求。接口没有实现,因为它是城堡类型的工厂设施。我将此类提供商注册为单例:

    Component.For().AsFactory()

我有意将其命名为 provider,因为它不会通过某些逻辑创建新的意图,而是为您提供已注册的实例。

  1. 界面必须如下所示:

    公共接口 IAnimalFactoryProvider { IEnumerable GetAllAnimalFactory(); 无效释放(I尼马尔工厂动物工厂); }

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

  3. 然后,根据您的 IAnimal 工厂,您可以在使用后释放它们,或者如果它们也是单例,您可以保留它们,当您的应用程序退出时,Castle 将处理它们。

另一种方法 - 类型化工厂作为委托描述在这里,这里,这里,这里和这里