Castle Windsor无法拦截为类实例注册的组件



我在拦截注册到类实体的组件时遇到问题。

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

如果我在不使用类实例的情况下注册组件,拦截器就会工作

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

这是一个错误还是故意的?

感谢

这是单元测试代码。

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

这是经过设计的。如果您手动实例化对象,就不能指望Windsor连接一个拦截器。

您实际上可以通过使用拦截器选择器来拦截已注册的实例,但如果它能像上面概述的"kite"一样工作,那就太好了。方法如下。这个例子是特定于我的实现的,但有足够的细节可以供您自己使用。

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

最新更新