城堡温莎代理没有目标的接口

时间:2010-10-31 05:56:47

标签: .net inversion-of-control castle-windsor castle-dynamicproxy

我有WindsorContainer IModelInterceptorsSelector。除了没有实现的组件之外(例如,所有行为都由IInterceptor动态处理),它运行良好。

如果我尝试仅使用接口解析组件,我会得到:

Castle.MicroKernel.ComponentActivator.ComponentActivatorException occurred
  Message=Could not find a public constructor for type ConsoleApplication1.IInterfaceOnlyService. Windsor can not instantiate types that don't expose public constructors. To expose the type as a service add public constructor, or use custom component activator.
  Source=Castle.Windsor
  StackTrace:
       at Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.FastCreateInstance(Type implType, Object[] arguments, Type[] signature)

但是如果我在注册时手动指定拦截器,它就可以了。这是温莎的错误还是我做错了什么?

重现的代码非常简单:

        var container = new WindsorContainer();
        container.Kernel.ProxyFactory.AddInterceptorSelector(new Selector());
        container.Register(Component.For<TestInterceptor>());
        container.Register(Component.For<IInterfaceOnlyService>()); // this doesn't work
        // container.Register(Component.For<IInterfaceOnlyService>().Interceptors<TestInterceptor>());  // this works
        var i = container.Resolve<IInterfaceOnlyService>();


    public class Selector : IModelInterceptorsSelector
    {
        public bool HasInterceptors(ComponentModel model)
        {
            return model.Service != typeof (TestInterceptor);
        }

        public InterceptorReference[] SelectInterceptors(ComponentModel model, InterceptorReference[] interceptors)
        {                
            return new[] { InterceptorReference.ForType<TestInterceptor>() };
        }
    }

感谢。

1 个答案:

答案 0 :(得分:0)

这肯定是温莎的一个错误。看起来它与接受没有目标的组件的InterceptorGroup有关。那就是:

container.Register(Component.For<IInterfaceOnlyService>  
().Interceptors<TestInterceptor>());

的工作原理。

container.Register(Component.For<IInterfaceOnlyService>  
().Interceptors(InterceptorReference.ForType(typeof(TestInterceptor))));

在查看Castle源时,区别在于第一个直接添加了adescriptor:

return this.AddDescriptor(new InterceptorDescriptor<TService>(new  
InterceptorReference[] { new InterceptorReference(typeof(TInterceptor)) }));

但是第二个在内部使用拦截器组:

return new InterceptorGroup<TService>((ComponentRegistration<TService>) this,   
interceptors);

因此,这似乎是InterceptorGroups中的一个错误。

我的解决方法(虽然hacky)是使用我的LazyComponentLoader直接调用AddDescriptor。