0

我有一個Windsor容器,我正在使用InterceptorSelector和LazyComponentLoader。Windsor攔截器異常

我InterceptorSelector返回InterceptorReference我InterceptorAdapter類,看起來像這樣

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>())); 

有什麼建議嗎?

謝謝!

回答

0

這似乎是Castle使用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)); 
      }   

似乎解決這個問題。