aop切片编程实现 #
一、实现原理 #
- 注入真正实现类;
- 替换实现类,将自行实现的代理类注入,替换真正的实现类,代理类的Target为目标真正实现类;
- 在代理类中使用反射,执行真正的实现类。
二、使用场景 #
- 权限
- 缓存
- 内容传递
- 记录跟踪(如业务节点上报、日志等)
- 错误处理
......
三、例子 #
需要更新框架最新版
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";
    }
}