代码之家  ›  专栏  ›  技术社区  ›  Jeff

Castle Windsor无目标接口代理

  •  0
  • Jeff  · 技术社区  · 14 年前

    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 回复  |  直到 14 年前
        1
  •  0
  •   Jeff    14 年前

    这肯定是温莎的一个虫子。看起来这与接受没有目标的组件的InterceptorGroup有关。即:

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

    作品。

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

    在查看城堡的来源时,不同之处在于第一个直接添加了adescriptor:

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

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

    因此,这似乎是拦截器组中的一个bug。

    我的解决方法(尽管很麻烦)是使用我的LazyComponentLoader直接调用AddDescriptor。