Windsor Interceptor Exception
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开发者_JAVA百科 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!
This seems to be a problem in the way Castle resolves Interceptors using an LazyComponentLoader.
Changing my code in the selector to do:
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));
}
Seems to fix the problem.
精彩评论