0

私は を持ってWindsorContainerIModelInterceptorsSelectorます。これは、実装のないコンポーネント (たとえば、すべての動作が によって動的に処理される) を除いて、うまく機能します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>() };
        }
    }

ありがとう。

4

1 に答える 1

0

これは間違いなく Windsor のバグのようです。ターゲットのないコンポーネントの InterceptorGroup を受け入れることに関係しているようです。あれは:

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

動作します。

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

Castle ソースを見ると、違いは、最初に descriptor を直接追加することです。

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

しかし、2 つ目は内部的にインターセプター グループを使用します。

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

したがって、これは InterceptorGroups のバグのようです。

私の回避策 (ハックですが) は、LazyComponentLoader を使用して AddDescriptor を直接呼び出すことです。

于 2010-11-04T17:14:22.467 に答える