Ner*_*roS 7 .net c# aop castle-windsor interceptor
我有一个抽象的基类,它包含几个方法,其中一个我需要随时拦截.基类可以由用户定义的类继承,并在应用程序启动时向容器注册.如果用户尚未注册,则容器安装程序将自行注册一个.
这是问题 - 用户不必担心添加拦截器.容器应该自己添加它,无论注册组件的人和位置.
这就是我现在正在做的事情:
if(!container.Kernel.HasComponent(typeof(MyBaseComponent)))
container.Register(Component.For<MyComponent>()
.Interceptors(InterceptorReference
.ForType<MyComponentMethodInterceptor>())
.SelectedWith(new MyComponentMethodSelector()).AtIndex(1));
Run Code Online (Sandbox Code Playgroud)
MyComponentMethodSelector是一个简单的IInterceptorSelector,它检查methodname是否等于我需要拦截的那个(在这种情况下MyComponentMethodInterceptor会添加一个).
如您所见,它将检查组件是否已首先注册.
问题是 - 如果已经注册,我是否有办法添加拦截器?想到的最明显的选择是使用a IContributeComponentModelConstruction,但是在那时我将无法选择拦截器添加到的方法.还是有吗?
编辑:
我本来应该更具体一点.我只需要为特定方法添加拦截器.因此我为什么使用MyComponentMethodSelector.我知道IContributeComponentModel,我开始用它直到我意识到我无法添加方法选择器.
您可以使用ComponentModel构造参与者轻松地将组件添加到组件,该构建参与者通过实现在构建服务的组件模型时调用IContributeComponentModelConstruction.
假设你想要为任何实现添加一个拦截器IEventuallyRegistered,如果用户没有注册你想要使用的自定义组件DefaultRegistration:
public interface IEventuallyRegistered { void test(); }
public class DefaultRegistration : IEventuallyRegistered { public void test() { } }
public class EventuallyRegisteredInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation) { invocation.Proceed(); }
}
internal class Program
{
private static void Main(string[] args)
{
var container = new Castle.Windsor.WindsorContainer();
container.Register(Component.For<EventuallyRegisteredInterceptor>());
container.Register(Component.For<IEventuallyRegistered>().ImplementedBy<DefaultRegistration>());
// I'm not doing the optional registration, I just want to
// demonstrate upgrading a additional configuration
var t = container.Resolve<IEventuallyRegistered>();
t.test();
}
}
Run Code Online (Sandbox Code Playgroud)
通过实现IContributeComponentModelConstruction界面,您可以在创建组件模型时更改其配置:
public class RequireInterception : IContributeComponentModelConstruction
{
public void ProcessModel(IKernel kernel, ComponentModel model)
{
if (model.Services.Contains(typeof(IEventuallyRegistered)))
{
model.Interceptors.Add(new InterceptorReference(typeof(EventuallyRegisteredInterceptor)));
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后在注册组件之前将组件添加到容器中:
container.Kernel.ComponentModelBuilder.AddContributor(new RequireInterception());
container.Register(Component.For<IEventuallyRegistered>().ImplementedBy<DefaultRegistration>());
Run Code Online (Sandbox Code Playgroud)
尽管可以通过ComponentRegistered具有工具的内核事件来实现,但不建议这样做 ; 因为它包含在原始答案中,所以我将其包括在内但我正在推动它.您将从创建工具开始
public class InterceptionFacility : AbstractFacility
{
protected override void Init()
{
Kernel.ComponentRegistered += new Castle.MicroKernel.ComponentDataDelegate(Kernel_ComponentRegistration);
}
void Kernel_ComponentRegistration(string key, Castle.MicroKernel.IHandler handler)
{
if (typeof(IEventuallyRegistered).IsAssignableFrom(handler.ComponentModel.Implementation))
{
handler.ComponentModel.Interceptors.Add(new InterceptorReference(typeof(EventuallyRegisteredInterceptor)));
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后在注册组件之前将工具添加到容器中,否则您的工具将在注册组件时错过该事件:
container.AddFacility<InterceptionFacility>();
container.Register(Component.For<IEventuallyRegistered>().ImplementedBy<DefaultRegistration>());
Run Code Online (Sandbox Code Playgroud)