使用Castle Windsor,我想获得实现特定界面的所有工厂的集合。
假设您有以下类型层次结构:
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.
答案 0 :(得分:2)
您必须执行以下步骤:
在工厂注册一个符合您需求的生命周期。该接口没有实现,因为它是castle typed factory facility.我将这些提供者注册为单身:
Component.For()。AsFactory()
我故意将其命名为提供者,因为它不会通过某些逻辑创建新的内容,但会为您提供已注册的实例。
界面必须如下所示:
公共接口IAnimalFactoryProvider { IEnumerable的&LT; IAnimalFactory&GT; GetAllAnimalFactories(); void Release(IAnimalFactory animalFactory); }
然后将IModuleModelInitializerProvider放入要注入的ctor中,然后通过方法GetAllAnimalFactories()获取所有hte实例。
然后根据你的IAnimal工厂,你可以在使用后释放它们,或者如果它们是单身,你也可以离开它们,Castle会在你的申请退出时处理它们。