温莎拦截器异常

发布于 2024-09-29 18:52:33 字数 3177 浏览 4 评论 0原文

我有一个 Windsor 容器,正在使用 InterceptorSelector 和 LazyComponentLoader。

我的 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: 

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

有什么建议吗?

谢谢!

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!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

谜泪 2024-10-06 18:52:33

这似乎是 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));
           }         

似乎可以解决问题。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文