C# AOP编程

AOP(面向切片编程的概念我这里就不介绍了,这里先介绍一下C#中的AOP编程框架。

1.AOP的分类

.net下支持AOP的框架很多,搜了一下有:PostSharp、AspectInjector、Fody 、Castle Windsor、Spring.NET、Ninject、Unity等,实现的方式主要氛围两大类:

  • 编译时织入:通常在运行时性能较好,但编译时间可能增加。上面的红色框架
  • 动态代理:通常在高频调用时会有额外的性能开销。上面的蓝色框架。

1.编译时织入举例

PostSharp是非开源的,这里以AspectInjector为例:

cs 复制代码
using AspectInjector.Broker;

Console.WriteLine("Hello, World!");
MyClass myClass = new MyClass();
myClass.MyMethod();


[Aspect(Scope.Global)]
[Injection(typeof(LogAttribute))]
public class LogAttribute : Attribute
{
    [Advice(Kind.Before)]
    public void Before([Argument(Source.Name)]string name)
    {
        Console.WriteLine($"Entering method: {name}");
    }

    [Advice(Kind.After)]
    public void After([Argument(Source.Name)] string name)
    {
        Console.WriteLine($"Exiting method: {name}");
    }
}

public class MyClass
{
    [Log]
    public void MyMethod()
    {
        Console.WriteLine("Executing MyMethod");
    }
}

运行结果如下:

cs 复制代码
Hello, World!
Entering method: MyMethod
Executing MyMethod
Exiting method: MyMethod

想了解更多可以参考AspectInjector的官方文档

2.动态代理举例

单纯的动态代理其实需要手动编写的代码较多,一般是结合依赖注入容器来使用。这个以比较常用的Autofac 依赖注入容器为例:

  • 首先,通过 NuGet 安装 Autofac 和动态代理支持:
cs 复制代码
Install-Package Autofac
Install-Package Autofac.Extras.DynamicProxy
  • 创建接口和实现类

定义一个接口和它的实现类:

cs 复制代码
public interface IMessageService
{
    void SendMessage(string message);
}

public class EmailService : IMessageService
{
    public void SendMessage(string message)
    {
        Console.WriteLine($"Email sent: {message}");
    }
}
    1. 创建拦截器

定义一个拦截器类,用于实现 AOP 功能:

cs 复制代码
using Castle.DynamicProxy;
using System;

public class LoggingInterceptor : IInterceptor
{
    public void Intercept(IInvocation invocation)
    {
        Console.WriteLine($"Entering method: {invocation.Method.Name}");
        invocation.Proceed(); // 调用原方法
        Console.WriteLine($"Exiting method: {invocation.Method.Name}");
    }
}

设置 Autofac 容器

在 Autofac 容器中注册服务和拦截器:

cs 复制代码
using Autofac;

public class Program
{
    static void Main(string[] args)
    {
        var builder = new ContainerBuilder();
        builder.RegisterType<EmailService>()
               .As<IMessageService>()
               .EnableInterfaceInterceptors()
               .InterceptedBy(typeof(LoggingInterceptor));

        builder.RegisterType<LoggingInterceptor>();

        var container = builder.Build();

        var messageService = container.Resolve<IMessageService>();
        messageService.SendMessage("Hello, Autofac with AOP!");
    }
}

运行结果:

cs 复制代码
Entering method: SendMessage
Email sent: Hello, Autofac with AOP!
Exiting method: SendMessage

可以看到我们成功的实现了在原函数前后插入执行代码。动态代理在web服务使用较多。

相关推荐
2501_930707781 小时前
使用C#代码在 PowerPoint 中组合或取消组合形状
开发语言·c#
baivfhpwxf20239 小时前
c# 中对像之间频繁的转换会慢吗?
开发语言·c#
加号311 小时前
【C#】 实现 XRC 异或冗余校验:原理与实践
c#·xrc
小钻风336611 小时前
Java + Spring Boot 操作 Kafka 完整学习指南
c#·linq
叫我少年11 小时前
C# 程序的常规结构 — 命名空间、类型、入口点与表达式
c#
行者-全栈开发15 小时前
SpringBoot AOP 面向切面编程实战|4大企业级案例+自定义注解+5个避坑指南
spring boot·aop·权限校验·自定义注解·日志记录·避坑指南·切面编程
步步为营DotNet16 小时前
探秘.NET 11:C# 14 特性在后端性能优化中的深度应用
性能优化·c#·.net
Chris _data16 小时前
C# 与 PLC Modbus RTU 通信实践:从单例到线程安全的连接监控
开发语言·安全·c#
Chris _data16 小时前
C# WinForms 后台轮询 Modbus 数据与 UI 更新实践
开发语言·ui·c#
魔法阵维护师17 小时前
从零开发游戏需要学习的c#模块,第二十四章(场景管理 —— 标题、游戏、结束画面)
学习·游戏·c#