How to programmatically register a component that depends on a list of already registered components with Castle Windsor?
我正在以编程方式注册一组服务,这些服务都实现了相同的接口 IRule。我有另一个看起来像这样的服务:
1 2 3 4 5 6 | public class MyService { private IEnumerable<IRule> _rules; public MyService(IEnumerable<IRule> rules){ _rules = rules; } } |
Hammett 发布了一些我想要的东西,http://hammett.castleproject.org/?p=257。我将签名更改为 IRule[] 并在帖子中尝试了 ArrayResolver 技巧,但这对我不起作用(注意,它也没有破坏任何东西)。
有人知道如何像我上面发布的代码那样以编程方式注册组件吗?
如果您不想更改 MyService 的签名并继续使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | public class EnumerableResolver : ISubDependencyResolver { private readonly IKernel kernel; public EnumerableResolver(IKernel kernel) { this.kernel = kernel; } public bool CanResolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, DependencyModel dependency) { Type targetType = dependency.TargetType; if (targetType == null) { throw new ArgumentException("TargetType property cannot be null","dependency"); } if (targetType.IsGenericType && (targetType.GetGenericTypeDefinition() == typeof(IEnumerable<>))) { Type service = targetType.GetGenericArguments()[0]; return this.kernel.HasComponent(service); } return false; } public object Resolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, DependencyModel dependency) { Type service = dependency.TargetType.GetGenericArguments()[0]; Array array = this.kernel.ResolveAll(service, (IDictionary)null); return Activator.CreateInstance(typeof(List<>).MakeGenericType(new Type[] { service }), new object[] { array }); } } |
它需要像这样在容器中注册:
1 | container.Kernel.Resolver.AddSubResolver(new EnumerableResolver(this.Kernel)); |
我加载了 Castle.MicroKernel 的源代码,并注意到已经有一个 ArrayResolver 和 ListResolver(在 Castle.MicroKernel.Resolvers.SpecializedResolvers 命名空间中)。我从 Hammet 的博客中(盲目地)复制的代码不起作用,很可能是因为框架在编写后发生了变化。
这里有一个示例项目演示如何执行此操作:http://www.panteravb.com/downloads/WindsorCon.zip
我尝试了 ArrayResolver 和 ListResolver,它们都可以顺利运行,这非常简单,所以假设这个服务类:
1 2 3 4 5 6 7 8 | public class MyService { private IEnumerable<IRule> _rules; public MyService(IList<IRule> rules) { _rules = rules; } } |
你可以这样注册这个人:
1 2 3 4 5 6 7 8 9 | private IWindsorContainer _container; private void InitializeIoc() { _container = new WindsorContainer(); _container.Kernel.Resolver.AddSubResolver(new ListResolver(_container.Kernel)); _container.Register(Component.For<IRule>().ImplementedBy<Rule1>()); _container.Register(Component.For<IRule>().ImplementedBy<Rule2>()); _container.Register(Component.For<MyService>()); } |