简体   繁体   English

Castle Windsor不能拦截为类实例注册的组件

[英]Castle Windsor Cannot Intercept Component Registered For A Class Instance

I have problem intercepting a component registered to a class intance. 我有问题拦截注册到类intance的组件。

//this does not get intercepted
container.Register(Component.For<IService>().Instance(instanceService)
                                .Interceptors<Interceptor>());

Interceptor works if I register the component without using the class instance 如果我在不使用类实例的情况下注册组件,Interceptor就可以工作

//this get intercepted
container.Register(Component.For<IService>().ImplementedBy<SampleService>()
                         .Interceptors<Interceptor>());

Is this a bug or by design? 这是一个bug还是设计?

Thanks 谢谢

This is unit test code. 这是单元测试代码。

    [Test]
    public void Test_Windsor_Interceptor_With_Instance_Component_Registration()
    {
        IService instanceService = new SampleService();

        var container = new WindsorContainer();
        container.Register(Component.For<Interceptor>());

        //this get intercepted
        container.Register(Component.For<IService>().ImplementedBy<SampleService>()
                            .Interceptors<Interceptor>());

        ////this does not get intercepted
        //container.Register(Component.For<IService>().Instance(instanceService)
        //                    .Interceptors<Interceptor>());

        var proxiedService = container.Resolve<IService>();

        proxiedService.DoSomething();


    }

    public class Interceptor : Castle.DynamicProxy.IInterceptor
    {
        public void Intercept(Castle.DynamicProxy.IInvocation invocation)
        {
            throw new System.NotImplementedException("Interceptor succesfully called but not implemented");
        }
    }

    public interface IService
    {
        void DoSomething();
    }

    public class SampleService : IService
    {
        public void DoSomething()
        {
            string dummy = string.Empty;
        }
    }

It's by design. 这是设计的。 You can't expect Windsor to wire up an interceptor if you're manually instantiating the object. 如果您手动实例化对象,则不能指望Windsor连接拦截器。

You actually can intercept a registered instance by using an interceptor selector, but it would be nice if it worked the way "kite" outlined above. 你实际上可以通过使用一个拦截器选择器拦截一个已注册的实例,但如果它按照上面概述的“风筝”方式工作会很好。 Here's how. 这是如何做。 This example is specific to my implementation, but there is enough detail to figure it out for your own usage. 这个例子特定于我的实现,但是有足够的细节来计算出你自己的用法。

StubISecurityService instance= new StubISecurityService();
Container.Register(Component.For<ISecurityService>().Instance(instance));

//Apply the interceptors.
Container.Kernel.ProxyFactory.AddInterceptorSelector(new InterceptorSelector<SecurityInterceptor>(model => model.Implementation == typeof(ExampleSecureService)));

IExampleSecureService exampleSecureService = Container.Resolve<IExampleSecureService>();

/// <summary>
/// A generic implementation of <see cref="IModelInterceptorsSelector"/> used to apply a single interceptor on matching types.
/// </summary>
/// <typeparam name="TInterceptor">The type of the interceptor.</typeparam>
public class InterceptorSelector<TInterceptor> : IModelInterceptorsSelector {
    private readonly Func<ComponentModel, bool> _selector;

    /// <summary>
    /// Initializes a new instance of the <see cref="InterceptorSelector{TInterceptor}"/> class.
    /// </summary>
    /// <param name="selector">The function used to find matching types.</param>
    public InterceptorSelector(Func<ComponentModel, bool> selector) {
        _selector = selector;
    }

    public virtual bool HasInterceptors(ComponentModel model) {
        bool isNotItself = typeof(TInterceptor) != model.Implementation;
        bool isMatch = _selector.Invoke(model);
        return isNotItself && isMatch;
    }

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM