0

InterceptorSelectorとLazyComponentLoaderを使用しているWindsorコンテナがあります。

私のInterceptorSelectorは、次のようなInterceptorAdapterクラスにInterceptorReferenceを返します。

public class InterceptorAdapter<T> : Castle.DynamicProxy.IInterceptor, IOnBehalfAware where T : IMyType
{
    private readonly T interceptor;

    public InterceptorAdapter(T interceptor)
    {
        this.interceptor = interceptor;
    }
    ....
}

したがって、InterceptorSelectorは

        public InterceptorReference[] SelectInterceptors(ComponentModel model, InterceptorReference[] interceptors)
        {
            var results = new List<InterceptorReference>();
            ....
            foreach (var interceptorType in someInterceptorTypes)
            {
                Type interceptorAdapterType = typeof(InterceptorAdapter<>).MakeGenericType(interceptorType);


               if (kernel.GetHandler(interceptorAdapterType) == null)
               { 
                 // need to do this or Castle complains it can't create my  
                 // interceptor...I guess LazyComponentLoaders don't work for InterceptorReferences?...  
                 // I suspect the problem may be here...
                 kernel.Register(lazyComponentLoader.Load(null, interceptorAdapterType, null));
               }                    

                results.Add(InterceptorReference.ForType(interceptorAdapterType));
            }
            return results.ToArray();
        }

InterceptorSelectorがInterceptorReferenceを初めて返すときは、うまく機能します。次回、InterceptorReferenceを別のジェネリック型引数を持つInterceptorAdapterに返すと、次のようになります。

Castle.MicroKernel.ComponentRegistrationException occurred
  Message=There is a component already registered for the given key interceptor
  Source=Castle.Windsor
  StackTrace:
       at Castle.MicroKernel.SubSystems.Naming.DefaultNamingSubSystem.Register(String key, IHandler handler) in c:\TeamCity\buildAgent\work\1ab5e0b25b145b19\src\Castle.Windsor\MicroKernel\SubSystems\Naming\DefaultNamingSubSystem.cs:line 75
  InnerException: 

私のLazyComponentLoaderは単純に

        public IRegistration Load(string key, Type service, IDictionary arguments)
        {
            ComponentRegistration<object> component = Component.For(service).Named(key);                

            if (arguments != null)
            {
                // merge is an extension method to merge dictionaries.
                component.DynamicParameters((k, d) => d.Merge(arguments));
            }
            return component;
        }

私のコンテナのセットアップは次のようになります

        var container = new WindsorContainer();

        container.AddFacility<TypedFactoryFacility>();
        container.AddFacility("factories", new FactorySupportFacility());

        container.Register(Component.For<ILazyComponentLoader>().ImplementedBy<MyLazyComponentLoader>().LifeStyle.Singleton);

        container.Kernel.ProxyFactory.AddInterceptorSelector(new InterceptorSelector(container.Kernel, container.Resolve<ILazyComponentLoader>()));

助言がありますか?

ありがとう!

4

1 に答える 1

0

これは、キャッスルが LazyComponentLoader を使用してインターセプターを解決する方法に問題があるようです。

セレクターのコードを次のように変更します。

           if (kernel.GetHandler(interceptorType) == null)
           { 
             // need to do this or Castle complains it can't create my  
             // interceptor...I guess LazyComponentLoaders don't work for InterceptorReferences?...  
             // I suspect the problem may be here...
             kernel.Register(lazyComponentLoader.Load(null, interceptorType, null));
           }                    

            Type interceptorAdapterType = typeof(InterceptorAdapter<>).MakeGenericType(interceptorType);


           if (kernel.GetHandler(interceptorAdapterType) == null)
           { 
             // need to do this or Castle complains it can't create my  
             // interceptor...I guess LazyComponentLoaders don't work for InterceptorReferences?...  
             // I suspect the problem may be here...
             kernel.Register(lazyComponentLoader.Load(null, interceptorAdapterType, null));
           }         

問題を解決するようです。

于 2010-11-04T17:16:39.737 に答える