温莎城堡:如何注入所有工厂的集合
本文关键字:工厂 集合 注入 城堡 何注入 | 更新日期: 2023-09-27 18:36:56
使用温莎城堡,我想获取实现特定接口的所有工厂的集合。
假设您具有以下类型层次结构:
public interface IAnimal { }
public class Cat : IAnimal { }
public class Dog : IAnimal { }
使用TypedFactoryFacility
我能够注入一个Func<IAnimal>
,该充当工厂来创建动物实例(具有瞬态生命周期)。我还可以使用CollectionResolver
来解决具有单例生命周期的动物集合。但在下面的示例中,似乎无法组合TypedFactoryFacility
和CollectionResolver
的效果来解析工厂集合。
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.
您必须执行以下步骤:
-
将接口注册为工厂,其生存期适合您的需求。接口没有实现,因为它是城堡类型的工厂设施。我将此类提供商注册为单例:
Component.For().AsFactory()
我有意将其命名为 provider,因为它不会通过某些逻辑创建新的意图,而是为您提供已注册的实例。
-
界面必须如下所示:
公共接口 IAnimalFactoryProvider { IEnumerable
GetAllAnimalFactory(); 无效释放(I尼马尔工厂动物工厂); } -
然后,将 IModuleModelInitializerProvider 放入要注入的 ctor 中,然后通过方法 GetAllAnimalFactory() 获取所有实例。
-
然后,根据您的 IAnimal 工厂,您可以在使用后释放它们,或者如果它们也是单例,您可以保留它们,当您的应用程序退出时,Castle 将处理它们。
另一种方法 - 类型化工厂作为委托描述在这里,这里,这里,这里和这里