aop切片编程实现 #

一、实现原理 #

  1. 注入真正实现类;
  2. 替换实现类,将自行实现的代理类注入,替换真正的实现类,代理类的Target为目标真正实现类;
  3. 在代理类中使用反射,执行真正的实现类。

二、使用场景 #

  1. 权限
  2. 缓存
  3. 内容传递
  4. 记录跟踪(如业务节点上报、日志等)
  5. 错误处理

......

三、例子 #

需要更新框架最新版

1、定义代理接口 #

public interface IDataReporting
{
}

2、定义代理实现 #

//TODO是需要自己加的业务
//可以利用Services获取已经注入的类,用来调用其他接口的方法,如var _service = Services.GetService<T>();
[SuppressSniffer]
    public class DataReporting : AspectDispatchProxy, IDispatchProxy
    {
        /// <summary>
        /// 被代理对象
        /// </summary>
        public object Target { get; set; }

        /// <summary>
        /// 服务提供器
        /// </summary>
        public IServiceProvider Services { get; set; }

        /// <inheritdoc/>

        public override object Invoke(MethodInfo method, object[] args)
        {
            //TODO
            var result = method.Invoke(Target, args);
            //TODO
            return result;
        }
/// <inheritdoc/>

        public override Task InvokeAsync(MethodInfo method, object[] args)
        {
            //TODO
            var result = (Task)method.Invoke(Target, args);
            //TODO
            return result;
        }
/// <inheritdoc/>

        public override Task<T> InvokeAsyncT<T>(MethodInfo method, object[] args)
        {
            //TODO
            var result = (Task<T>)method.Invoke(Target, args);
            //TODO
            return result;
        }
    }

3、注入 #

1、本项目使用 #

//在程序入口(.net 6风格入口在Program.cs,其他在Startup.cs)添加代码
services.AddScopedDispatchProxyForInterface<DataReporting, IDataReporting>();

2、提供其他项目使用 #

//当然,这也可以本项目使用,不过要提供给其他项目使用,要注意依赖关系问题。 //添加扩展方法,如:

//当然,这也可以本项目使用,不过要提供给其他项目使用,要注意依赖关系问题。
//添加扩展方法,如:
public static class DataReportingCollectionExtensions
    {
        public static IServiceCollection AddDataReporting(this IServiceCollection services)
        {
            services.AddScopedDispatchProxyForInterface<DataReporting, IDataReporting>();

            return services;
        }
    }

4、使用 #

4.1、接口 #

//需要实现代理接口(本案例的代理接口是IDataReporting)

public interface ITestProxyService : IDataReporting
 {
 Task Test1();
 Task<string> Test2(string aaa);

  void Test3();

 string Test4();
}

4.2、实现类 #

//需要实现接口生命周期(本案例是ITransient)

    public class TestProxyService : ITestProxyService , ITransient
    {
        public async Task Test1()
        {
            Console.WriteLine("Test1");
        }
        
     public async Task<string> Test2(string aaa)
    {
        Console.WriteLine("Test2");
        return await Task.FromResult(aaa);
    }

    public void Test3()
    {
        Console.WriteLine("Test3");
    }

    public string Test4()
    {
        Console.WriteLine("Test4");
        return "Test4";
    }
}
上次更新: 3/10/2023, 5:03:49 PM