0

J'ai un conteneur Windsor avec lequel j'utilise un InterceptorSelector et un LazyComponentLoader.Windsor Interceptor Exception

Mon InterceptorSelector retourne un InterceptorReference à ma classe InterceptorAdapter qui ressemble à ceci

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

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

de sorte que le InterceptorSelector-t

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

choses fonctionnent très bien la première fois que mon InterceptorSelector retourne un InterceptorReference. La prochaine fois, quand il retourne un InterceptorReference à un InterceptorAdapter avec un autre argument de type générique, je reçois

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: 

Mon LazyComponentLoader ne suffit

 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; 
     } 

Mon installation de conteneurs ressemble

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

Des suggestions?

Merci!

Répondre

0

Cela semble être un problème dans la façon dont Castle résout Interceptors en utilisant un LazyComponentLoader.

Changer mon code dans le sélecteur faire:

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

semble résoudre le problème.

Questions connexes