ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

.NET Core 实现动态代理 AOP

2022-01-06 12:32:21  阅读:119  来源: 互联网

标签:Core object args result AOP NET 执行 public ex


AOP实现

class DynamicProxy<T> : DispatchProxy
{
    public T? decorated { get; set; }//目标类  
    public Action<object?[]?>? _beforeAction { get; set; }  // 动作之后执行  
    public Action<object?[]?, object>? _afterAction { get; set; } // 动作之前执行

    protected override object? Invoke(MethodInfo? targetMethod, object?[]? args)
    {
        Exception exception = null;

        BeforeAction(args);
        object result = null;
        try
        {
            //调用实际目标对象的方法  
            result = targetMethod?.Invoke(decorated, args);
        }
        catch (Exception ex)
        {
            exception = ex;
        }
        AfterAction(args, result);
        //调用完执行方法后的委托,如果有异常,抛出异常  
        if (exception != null)
        {
            throw exception;
        }
        return result;
    }

    /// <summary>  
    /// 创建代理实例  
    /// </summary>  
    /// <param name="decorated">代理的接口类型</param>  
    /// <param name="beforeAction">方法执行前执行的事件</param>  
    /// <param name="afterAction">方法执行后执行的事件</param>  
    /// <returns></returns>  
    public T Create(T decorated, Action<object?[]?> beforeAction, Action<object?[]?, object> afterAction)
    {
        object proxy = Create<T, DynamicProxy<T>>(); // 调用DispatchProxy 的Create  创建一个新的T  
        DynamicProxy<T> proxyDecorator = (DynamicProxy<T>)proxy;
        proxyDecorator.decorated = decorated;
        //把自定义的方法委托给代理类  
        proxyDecorator._beforeAction = beforeAction;
        proxyDecorator._afterAction = afterAction;
        return (T)proxy;
    }


    private void BeforeAction(object?[]? args)
    {
        try
        {
            _beforeAction.Invoke(args);
        }
        catch (Exception ex)
        {
            Console.WriteLine($"执行之前异常:{ex.Message},{ex.StackTrace}");
        }
    }

    private void AfterAction(object?[]? args, object? result)
    {
        try
        {
            _afterAction.Invoke(args, result);
        }
        catch (Exception ex)
        {
            Console.WriteLine($"执行之后异常:{ex.Message},{ex.StackTrace}");
        }
    }
}

interface IInterceptor
{
    /// <summary>  
    /// 执行之前  
    /// </summary>  
    /// <param name="args">参数</param>  
    void BeforeAction(object?[]? args);

    /// <summary>  
    /// 执行之后  
    /// </summary>  
    /// <param name="args">参数</param>  
    /// <param name="result">结果</param>  
    void AfterAction(object?[]? args, object result);
}

[AttributeUsage(AttributeTargets.Class)]
class InterceptAttribute : Attribute
{
    public Type Type { get; set; }
    public InterceptAttribute(Type type)
    {
        this.Type = type;
    }
}

class ProxyFactory
{
    /// <summary>  
    /// 创建代理实例  
    /// </summary>  
    /// <param name="decorated">代理的接口类型</param>  
    /// <returns></returns>  
    public static T Create<T>()
    {
        T decorated = ServiceHelper.GetService<T>();
        Type type = decorated.GetType();
        InterceptAttribute attrib = type.GetCustomAttribute<InterceptAttribute>();
        IInterceptor interceptor = ServiceHelper.GetService<IInterceptor>(attrib.Type);

        //创建代理类  
        return new DynamicProxy<T>().Create(decorated, interceptor.BeforeAction, interceptor.AfterAction);
    }
}

static class ServiceHelper
{
    public static IServiceProvider? serviceProvider { get; set; }

    public static void BuildServiceProvider(IServiceCollection serviceCollection)
    {
        //构建容器  
        serviceProvider = serviceCollection.BuildServiceProvider();
    }

    public static T GetService<T>(Type serviceType)
    {
        return (T)serviceProvider.GetService(serviceType);
    }

    public static T GetService<T>()
    {
        return serviceProvider.GetService<T>();
    }
}

AOP使用

class AOPTest : IInterceptor
{
    void IInterceptor.BeforeAction(object[] args)
    {
        Console.WriteLine($"AOP方法执行之前,args:{args}");
        //throw new Exception("异常测试(异常,但依然不能影响程序执行)");
    }
     void IInterceptor.AfterAction(object[] args, object result)
    {
        Console.WriteLine($"AOP方法执行之后,args:{args},result:{result}");
    }
}

interface ITestService
{
    public int Add(int a, int b);
}

[Intercept(typeof(AOPTest))]
class TestService : ITestService
{
    int ITestService.Add(int a, int b)
    {
        Console.WriteLine($"正在执行--》Add({a},{b})");

        //throw new Exception("方法执行--》测试异常");
        return a + b;
    }
}

测试

    IServiceCollection = new ServiceCollection();
    serviceCollection.AddTransient(typeof(AOPTest));
    serviceCollection.AddTransient<ITestService, TestService>();
    //构建容器  
    ServiceHelper.BuildServiceProvider(serviceCollection);

    //用工厂获取代理实例  
    var s = ProxyFactory.Create<ITestService>();
    var sum = s.Add(1, 2);
    Console.WriteLine("执行完毕=====>" + sum);

测试输出

AOP方法执行之前,args:System.Object[]
正在执行--》Add(1,2)
AOP方法执行之后,args:System.Object[],result:3
执行完毕=====>3

转自:极客Bob
链接:cnblogs.com/Bob-luo/p/15716592.html

标签:Core,object,args,result,AOP,NET,执行,public,ex
来源: https://www.cnblogs.com/mryux/p/15770553.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有