没有目标的温莎城堡代理接口

发布于 2024-09-30 03:27:38 字数 1747 浏览 10 评论 0原文

我有一个带有 IModelInterceptorsSelectorWindsorContainer。它工作得很好,除了没有实现的组件(例如,所有行为都由 IInterceptor 动态处理)。

如果我尝试仅使用接口解析组件,我会得到:

Castle.MicroKernel.ComponentActivator.ComponentActivatorException occurred
  Message=Could not find a public constructor for type ConsoleApplication1.IInterfaceOnlyService. Windsor can not instantiate types that don't expose public constructors. To expose the type as a service add public constructor, or use custom component activator.
  Source=Castle.Windsor
  StackTrace:
       at Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.FastCreateInstance(Type implType, Object[] arguments, Type[] signature)

但如果我在注册时手动指定拦截器,它就可以正常工作。这是温莎的错误还是我做错了什么?

要重现的代码相当简单:

        var container = new WindsorContainer();
        container.Kernel.ProxyFactory.AddInterceptorSelector(new Selector());
        container.Register(Component.For<TestInterceptor>());
        container.Register(Component.For<IInterfaceOnlyService>()); // this doesn't work
        // container.Register(Component.For<IInterfaceOnlyService>().Interceptors<TestInterceptor>());  // this works
        var i = container.Resolve<IInterfaceOnlyService>();


    public class Selector : IModelInterceptorsSelector
    {
        public bool HasInterceptors(ComponentModel model)
        {
            return model.Service != typeof (TestInterceptor);
        }

        public InterceptorReference[] SelectInterceptors(ComponentModel model, InterceptorReference[] interceptors)
        {                
            return new[] { InterceptorReference.ForType<TestInterceptor>() };
        }
    }

谢谢。

I have a WindsorContainer with a IModelInterceptorsSelector. It works well except for component's that have no implementation (eg. have all behavior handled dynamically by an IInterceptor).

If I try to resolve a component with an interface only, I get:

Castle.MicroKernel.ComponentActivator.ComponentActivatorException occurred
  Message=Could not find a public constructor for type ConsoleApplication1.IInterfaceOnlyService. Windsor can not instantiate types that don't expose public constructors. To expose the type as a service add public constructor, or use custom component activator.
  Source=Castle.Windsor
  StackTrace:
       at Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.FastCreateInstance(Type implType, Object[] arguments, Type[] signature)

But if I manually specify the interceptor at registration time, it works just fine. Is this a bug in Windsor or am I doing something wrong?

The code to reproduce is fairly straightforward:

        var container = new WindsorContainer();
        container.Kernel.ProxyFactory.AddInterceptorSelector(new Selector());
        container.Register(Component.For<TestInterceptor>());
        container.Register(Component.For<IInterfaceOnlyService>()); // this doesn't work
        // container.Register(Component.For<IInterfaceOnlyService>().Interceptors<TestInterceptor>());  // this works
        var i = container.Resolve<IInterfaceOnlyService>();


    public class Selector : IModelInterceptorsSelector
    {
        public bool HasInterceptors(ComponentModel model)
        {
            return model.Service != typeof (TestInterceptor);
        }

        public InterceptorReference[] SelectInterceptors(ComponentModel model, InterceptorReference[] interceptors)
        {                
            return new[] { InterceptorReference.ForType<TestInterceptor>() };
        }
    }

Thanks.

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

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

发布评论

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

评论(1

回忆追雨的时光 2024-10-07 03:27:39

这绝对是温莎的一个错误。看起来它与接受没有目标的组件的 InterceptorGroup 有关。那就是:

container.Register(Component.For<IInterfaceOnlyService>  
().Interceptors<TestInterceptor>());

作品。

container.Register(Component.For<IInterfaceOnlyService>  
().Interceptors(InterceptorReference.ForType(typeof(TestInterceptor))));

查看 Castle 源代码,不同之处在于第一个直接添加描述符:

return this.AddDescriptor(new InterceptorDescriptor<TService>(new  
InterceptorReference[] { new InterceptorReference(typeof(TInterceptor)) }));

但第二个在内部使用拦截器组:

return new InterceptorGroup<TService>((ComponentRegistration<TService>) this,   
interceptors);

因此,这似乎是 InterceptorGroups 中的错误。

我的解决方法(虽然很hacky)是使用我的 LazyComponentLoader 直接调用 AddDescriptor。

This definitely seems to be a bug in Windsor. It looks like it has to do with accepting an InterceptorGroup for components without a target. That is:

container.Register(Component.For<IInterfaceOnlyService>  
().Interceptors<TestInterceptor>());

works.

container.Register(Component.For<IInterfaceOnlyService>  
().Interceptors(InterceptorReference.ForType(typeof(TestInterceptor))));

In looking at the Castle source, the difference is that the first adds adescriptor directly:

return this.AddDescriptor(new InterceptorDescriptor<TService>(new  
InterceptorReference[] { new InterceptorReference(typeof(TInterceptor)) }));

But the second uses an interceptor group internally:

return new InterceptorGroup<TService>((ComponentRegistration<TService>) this,   
interceptors);

Accordingly, this seems to be a bug in InterceptorGroups.

My workaround (although hacky) is to use my LazyComponentLoader to call AddDescriptor directly.

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