1

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

//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;
        }
    }
4

2 回答 2

2

这是设计使然。如果您手动实例化对象,则不能指望 Windsor 连接拦截器。

于 2012-08-28T23:54:42.440 回答
2

实际上,您可以使用拦截器选择器拦截已注册的实例,但如果它以上述“风筝”的方式工作,那就太好了。就是这样。这个例子是特定于我的实现的,但是有足够的细节来解决你自己的使用。

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>()};
    }
}
于 2013-07-03T05:42:20.797 回答