interface - 使用 CaSTLe Windsor 3.0 拦截 Startable 设施调用的方法

标签 interface dependency-injection castle-windsor aop interceptor

我正在使用温莎城堡 3.0。

我有一个组件应该在注册阶段后自动启动。 我还想拦截来自其 Start/Stop 方法的异常并记录其详细信息。

为了使我的组件可启动,我使用了 Windsor 附带的可启动工具:

container.AddFacility<StartableFacility>(f => f.DeferredStart());

我创建了一个像这样的自定义拦截器:

class ExceptionLoggerInterceptor : IInterceptor
{
    IExceptionLogger m_ExceptionLogger;

    public ExceptionLoggerInterceptor(IExceptionLogger exceptionLogger)
    {
        if (exceptionLogger == null)
            throw new ArgumentNullException("exceptionLogger");

        m_ExceptionLogger = exceptionLogger;
    }

    public void Intercept(IInvocation invocation)
    {
        try
        {
            invocation.Proceed();
        }
        catch (Exception ex)
        {
            m_ExceptionLogger.Write(ex, invocation.Method.Name, invocation.TargetType.Name);
        }
    }
}

我像这样注册了组件:

Component.For<IExceptionLogger>()
 .ImplementedBy<EnterpriseLibraryExceptionLogger>()
 .LifeStyle.Singleton,

Component.For<ExceptionLoggerInterceptor>()
 .LifeStyle.Singleton,

Component.For<IWorkflowService>()
 .ImplementedBy<WorkflowService>()
 .LifeStyle.Singleton
 .StartUsingMethod(c => c.Start)
 .StopUsingMethod(c => c.Stop)
 .Interceptors(InterceptorReference.ForType<ExceptionLoggerInterceptor>()).Anywhere

为了进行测试,我编写了一个脏代码

throw new Exception(); 

在组件的Start方法的实现中。在注册阶段,当Windsor自动调用组件上的Start方法时,会抛出异常,但从未被我的自定义拦截器拦截。

我做了另一个测试,这次没有使用 Startable 工具,而是手动调用 Start 方法。异常被抛出并被我的自定义拦截器拦截。

那么,正如本文标题所问,有没有办法用 Windsor 拦截 Startable 设施调用的方法?

问候

路易斯-皮埃尔·博蒙特

最佳答案

我将部分回答我自己的问题:

在使用 Startable 工具时,我没有找到任何方法来拦截组件上的 Start 方法。看起来该工具没有使用为对象创建的代理来执行调用,而是使用对象本身。

专门的帖子提出了这个问题here .

无论如何,我很快就发现使用代理对象进行 AOP 有其局限性。这就是我转向 SheepAspect(一个 IL Weaving AOP 框架)的原因。

我将 SheepAspect 与 CaSTLe Windsor 混合在一起,现在,当 CaSTLe Startable 设施调用我的组件的 Start 方法时,我的所有方面也会被调用!

这是我如何使用 SheepAspect 编写 ExceptionAspect:

[SingletonAspect]
public class ExceptionAspect
{
    IExceptionLogger m_ExceptionLogger;

    public ExceptionAspect(IExceptionLogger exceptionLogger)
    {
        if (exceptionLogger == null)
            throw new ArgumentNullException("exceptionLogger");

        m_ExceptionLogger = exceptionLogger;
    }

    [SelectTypes(typeof(WorkflowService))]
    void Targets() { }

    [Around("Execute")]
    [SelectMethods("Name:('Start') & InType:@Targets")]
    public void Execute(MethodJointPoint jp)
    {
        object result = null;

        try
        {
            result = jp.Execute();
        }
        catch (Exception ex)
        {
            m_ExceptionLogger.Write(ex, jp.Method.Name, jp.Method.ReflectedType.Name);
        }

        return result;
    }
}

关于interface - 使用 CaSTLe Windsor 3.0 拦截 Startable 设施调用的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8735534/

相关文章:

ios - 在给出退出操作时,unwind segue 不会出现在界面构建中

java - 在Java中,当一个接口(interface) "extends"另一个接口(interface)时到底会发生什么?

php - 可以访问 PHP MVC 框架中的公共(public)类

caSTLe-windsor - 温莎,在类里面注入(inject)容器

language-agnostic - 没有共同点的类的接口(interface)

java - 为什么要在 Java 中使用静态嵌套接口(interface)?

ios - SwiftUI:将多个 BindableObjects 放入环境

javascript - 如何抽象出浏览器窗口对象的用法?

c# - 温莎城堡 : Can a Typed Factory Facility pass a parameter down to one of the type's dependencies?

c# - 如何在服务中获取 Controller 的 ModelState 以进行验证