views:

24

answers:

1

I have a Windsor container that I'm using an InterceptorSelector and a LazyComponentLoader with.

My InterceptorSelector returns an InterceptorReference to my InterceptorAdapter class that looks like this

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

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

so the InterceptorSelector does

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

Things work great the first time my InterceptorSelector returns an InterceptorReference. The next time, when it returns an InterceptorReference to an InterceptorAdapter with a different generic type argument, I get

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: 

My LazyComponentLoader simply does

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

My container setup looks like

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

Any suggestions?

Thanks!