c# - 如何使用 CaSTLe Core 或其他库(只是免费库)编写拦截器(AOP)来解决横切问题

标签 c# aop interceptor castle-dynamicproxy interception

我想要一个像这样的属性来处理横切关注点,例如 Logging 、 Exception 等

public class MyService
{

[Log] // Interception (AOP)
[ExceptionHandler] // Interception (AOP)
public void DoSomething()
   {

   }
}

我知道我可以使用 postsharp 编写这些代码,但我想使用 CaSTLe Core 等免费库编写这些拦截......

任何人都可以帮助我并为此目的编写一个示例吗??? 我需要一个非常简单的示例来学习概念

最佳答案

Autofac 是一个免费的 IoC 容器。我将 Autofac 与 Autofac.Extras.DynamicProxy2 nuget 一起使用, docs .

假设您知道为什么以及何时(而不是)使用拦截器,并且您想要拦截某些功能:

public class FooService : IFooService
{
    public void MoreFoo()
    {
        DoSomething();
    }
    public void LessFoo()
    {
        DoSomethingElse();
    }
}

它需要“有线”。我喜欢属性,因为您不需要在 IoC 容器接线时显式指定拦截器。您只需指定要注意的属性:

[Intercept(typeof(Logger)]
public class FooService : IFooService { ... }

并接线:

var builder = new ContainerBuilder();
builder.RegisterType<FooService>()
   .EnableClassInterceptors();

然后在另一个文件中创建 Logger 拦截器:

class Logger : IInterceptor
{
    public void Intercept(IInvocation invocation) // implements the IInterceptor interface
    {
        _loggerService.Log("calling " + invocation.Method.Name);
        invocation.Proceed();
        _loggerService.Log("finished " + invocation.Method.Name);
    }
}

如您所见,您可以创建计时器、try-catch block 等等。数据库上下文和其他一次性资源是一个有趣的资源:

class Logger : IInterceptor
{
    public void Intercept(IInvocation invocation) // implements the IInterceptor interface
    {
        using (var someThing = new SomeResource())
        {
            invocation.Proceed();
        }
    }
}

通常对于这样的资源,您需要在方法中使用 someThing。这是另一个问题的主题! (请参阅 invoking.SetArgumentValue 或 invoking.TargetType.GetProperties() 与封闭类进行通信。我对此不是 100% 满意,因此其他人的一些评论会有所帮助)

然后,以日志记录为例:

void ManageFoo()
{
    // sorry for the messy code, what else can I do?!
    _logger("more foo please");
    _fooService.MoreFoo();
    _logger("less foo please");
    _fooService.LessFoo();
    _logger("enough foo");
}

ManageFoo 方法的实际关注点在所有困惑的日志记录中消失了(添加安全性和其他问题,最终可能会陷入一团糟)。

现在你可以像这样重写它:

void ManageFoo()
{
    _fooService.MoreFoo();
    _fooService.LessFoo();
}

关于c# - 如何使用 CaSTLe Core 或其他库(只是免费库)编写拦截器(AOP)来解决横切问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27473012/

相关文章:

c# - 我应该给这个 cookie 什么域?

c# - 在 C# 中按字符拆分字符串

c# - 使控件及其字体更大

c# - 后锐利。如何引入可序列化属性

c# - 我应该如何编写 XML 注释以避免在摘要和返回标记之间重复自己?

spring-mvc - Spring MVC 中未调用方面

java - 如何在具有周围建议的构造函数上应用切入点?

spring - 如何在 HandlerInterceptorAdapter 中使用 @ResponseBody 记录 Spring 3 Controller 的 JSON 响应?

java - Spring RestController - 拦截方法调用

java - 如何从地址拦截器更改一个订单的 OrderStatus?海布里斯商务