我在拦截注册到类实体的组件时遇到问题。
//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>()};
}
}