如何解决城堡拦截器:如何将拦截器添加到所有已注册类型?
| 我正在一对一地注册几种类型:container.Register(
Component.For<IService1>().ImplementedBy<ServiceImpl1>(),Component.For<IService2>().ImplementedBy<ServiceImpl2>(),Component.For<IService3>().ImplementedBy<ServiceImpl3>(),Component.For<IService4>().ImplementedBy<ServiceImpl4>()
);
有没有一种方法可以为已注册的所有此类程序集注册拦截器?我不想像AllTypes
那样按惯例注册所有类型。我只想添加一个拦截器而无需编写
.Interceptors(InterceptorReference.ForType<DummyInterceptor>())
.SelectedWith(new FooInterceptorSelector()).Anywhere
成千上万次。
谢谢!
解决方法
使用ComponentModel贡献者时,如何指定.SelectedWith?
通过执行此操作,我可以为所有方法添加一个拦截器。
public class MyContributor : IContributeComponentModelConstruction
{
public void ProcessModel(IKernel kernel,ComponentModel model)
{
model.Dependencies.Add(new DependencyModel(DependencyType.Service,null,typeof(MyInterceptor),false));
model.Interceptors.AddFirst(InterceptorReference.ForType<MyInterceptor>());
}
}
,正如Dan所建议的,可以使用自定义ComponentModel构造贡献者来实现。
首先,请注意
...
.Interceptors(InterceptorReference.ForType<DummyInterceptor>())
.SelectedWith(new FooInterceptorSelector())
.Anywhere
基本上相当于
...
.SelectInterceptorsWith(new FooInterceptorSelector())
.Interceptors(InterceptorReference.ForType<DummyInterceptor>())
.Anywhere
也就是说,将IInterceptorSelector
与ComponentModel
相关联与注册将使用IInterceptorSelector
选择的拦截器无关。此外,每个“ 7”只能有一个拦截器选择器。
由于这种分离,使用两个独立的贡献者可以最好地解决该问题-一个用于注册拦截器,另一个用于注册拦截器选择器。
第一个与Dan的答案基本相同。但是,没有必要为拦截器添加“ 10”,因为拦截器应该已经使用类似以下方式在容器中注册了
container.Register(Component.For<DummyInterceptor>().LifestyleTransient());
所以看起来可能像
using Castle.Core;
using Castle.MicroKernel;
using Castle.MicroKernel.ModelBuilder;
...
public class InterceptorContributor : IContributeComponentModelConstruction
{
private readonly InterceptorReference interceptor;
public InterceptorContributor(InterceptorReference interceptor)
{
this.interceptor = interceptor;
}
public void ProcessModel(IKernel kernel,ComponentModel model)
{
if (...)
{
model.Interceptors.Add(interceptor)
}
}
}
或者如果您希望能够一次性注册多个拦截器,则可以利用InterceptorDescriptor
的现有实现,而改为:
using System;
using Castle.Core;
using Castle.MicroKernel;
using Castle.MicroKernel.ModelBuilder;
using Castle.MicroKernel.ModelBuilder.Descriptors;
...
public class InterceptorsContributor : IContributeComponentModelConstruction
{
private readonly Predicate<ComponentModel> predicate;
private readonly IComponentModelDescriptor interceptorsDescriptor;
public InterceptorsContributor(Predicate<ComponentModel> predicate,params InterceptorReference[] interceptors)
{
this.predicate = predicate ?? throw new ArgumentNullException(nameof(predicate));
interceptorsDescriptor = new InterceptorDescriptor(interceptors);
}
public void ProcessModel(IKernel kernel,ComponentModel model)
{
if (predicate.Invoke(model))
{
interceptorsDescriptor.BuildComponentModel(kernel,model);
interceptorsDescriptor.ConfigureComponentModel(kernel,model);
}
}
}
要注册“ 6”,可以通过执行“ 16”来实现贡献者:
public void ProcessModel(IKernel kernel,ComponentModel model)
{
if (...)
{
var options = model.ObtainProxyOptions();
options.Selector = new InstanceReference<IInterceptorSelector>(selector);
}
}
或直接使用InterceptorSelectorDescriptor
:
using System;
using Castle.Core;
using Castle.DynamicProxy;
using Castle.MicroKernel;
using Castle.MicroKernel.ModelBuilder;
using Castle.MicroKernel.ModelBuilder.Descriptors;
...
public class InterceptorSelectorContributor : IContributeComponentModelConstruction
{
private readonly Predicate<ComponentModel> predicate;
private readonly IComponentModelDescriptor interceptorSelectorDescriptor;
public InterceptorSelectorContributor(Predicate<ComponentModel> predicate,IInterceptorSelector selector)
{
this.predicate = predicate ?? throw new ArgumentNullException(nameof(predicate));
var selectorRef = new InstanceReference<IInterceptorSelector>(selector);
interceptorSelectorDescriptor = new InterceptorSelectorDescriptor(selectorRef);
}
public void ProcessModel(IKernel kernel,ComponentModel model)
{
if (predicate.Invoke(model))
{
interceptorSelectorDescriptor.BuildComponentModel(kernel,model);
interceptorSelectorDescriptor.ConfigureComponentModel(kernel,model);
}
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。