0

我有一个使用 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>()));

有什么建议么?

谢谢!

4

1 回答 1

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

似乎可以解决问题。

于 2010-11-04T17:16:39.737 回答