首页 > 作文

.NET Core利用动态代理实现AOP(面向切面编程)

更新时间:2023-04-04 13:55:11 阅读: 评论:0

目录
1.介绍1.1 动态代理作用1.2 原生dispatchproxy类介绍1.3简单介绍一下:il代码2.实现2.1 继承dispatchproxy2.2 定义handle接口2.3 定义aop特性2.4 定义创建代理类的工厂2.5 定义rvicehelp3.测试3.1 定义handle实现3.2 定义rvice接口3.3实现rvice接口3.4 大功告成3.5 效果4.demo

1.介绍

1.1 动态代理作用

用动态代理可以做aop(面向切面编程),进行无入侵式实现自己的扩展业务,调用者和被调用者之间的解耦,提高代码的灵活性和可扩展性,比如:日志记录、性能统计、安全控制、事务处理、异常处理等等。本方式实现思路用的.net core原生的dispatchproxy类,再加《特性标记》+《handle接口》达到无入侵式扩展,有兴趣的朋友,自行改进一下,封装成组件。

有什么做的不好的或者建议,希望大家及时提出,帮助改进。

代码上传在gitee:https://gitee.com/luoxiangbao/dynamic-proxy.git

1.2 原生dispatchproxy类介绍

dispatchproxy我去看了一下源码,和我设想的差不多,就是emit类库直接编写il语言,动态生成类和方法,然后在方法里调用invoke方法,这个时候就我们只需要重写invoke方法,具体实现由我们自己管控。其性能很高,几乎和我们写好的c#编译成il没多大区别,大家用的autofac的aop,我也看了一下,底层用的是castle.core类库,而castle.core底层还是用的emit方式实现,只是思路不同。

便于理解我给大家贴一下源码:

1.定义抽象dispatchproxy类的invoke元数据

2.emit类库直接编写il语言,为代理类添加调用invoke方法代码

1.3简单介绍一下:il代码

il是.net框架中间语言(intermediate language),编译器可以直接将源程序编译为.exe或.dll文件,而clr(公共语言运行时)执行的是il语言,不是c#高级编程语言,il代码是一种近似于指令式的代码语言,与汇编语言比较相近,给大家做个案例对比一下。

c#代码:

class program    {        static void main(string[] args)        {            console.writeline("hello world!");        }    }

il代码:

il_0000:  nopil_0001:  ldstr      "hello world!"il_0006:  call       void [system.console]system.console::writeline(string)il_000b:  nopil_000c:  ret

有兴趣的朋友自己也可以去实现。接下来进入正题,我们怎么利用dispatchproxy自己造轮子!!!

2.实现

2.1 继承dispatchproxy

核心类就是,dispatchproxy。这是.net core 原生的。会帮我们创建一个代理类

internal class dynamicproxy<t> : dispatchproxy    {        public t? decorated { get; t; }//目标类        public action<object?[]?>? _afteraction { get; t; }  // 动作之后执行        public action<object?[]?, object>? _beforeaction { get; t; } // 动作之前执行        protected override object? invoke(methodinfo? targetmethod, object?[]? args)        {            exception exception = null;            afteraction(args);            object result = null;            try            {                //调用实际目标对象的方法                result = targetmethod?.invoke(decorated, args);            }            catch (exception ex)            {                exception = ex;            }            beforeaction(args, result);            //调用完执行方法后的委托,如果有异常,抛出异常            if (exception != null)            {                throw exception;            }            return result;        }  520给女朋友的话      /// <summary>        /// 创建代理实例        /// </summary>        /// <param name="decorated">代理的接口类型</param>        /// <param name="afteraction">方法执行前执行的事件</param>        /// <param name="beforeaction">方法执行后执行的事件</param>        /// <returns></returns>        public t create(t decorated, action<object?[]?> afteraction, action<object?[]?, object> beforeaction)        {            object proxy = create<t, dynamicproxy<t>>(); // 调用dispatchproxy 的create  创建一个新的t            dynamicproxy<t> proxydecorator = (dynamicproxy<t>)proxy;            proxydecorator.decorated = decorated;            //把自定义的方法委托给代理类            proxydecorator._aftera等不到天黑烟火不会太完美ction = afteraction;            proxydecorator._beforeaction = beforeaction;            return (t)proxy;        }        private void afteraction(object?[]? args)        {            try            {                _afteraction.invoke(args);            }            catch (exception ex)            {                console.writeline($"执行之前异常:{ex.message},{ex.stacktrace}");            }        }        private void beforeaction(object?[]? args, object? result)        {            try            {                _beforeaction.invoke(args, result);            }            catch (exception ex)            {                console.writeline($"执行之后异常:{ex.message},{ex.stacktrace}");            }        }    }

2.2 定义handle接口

这个接口定义:执行之前、执行之后两个方法。用来实现具体业务逻辑的处理

internal interface iinterceptor    {        /// <summary>        /// 执行之前        /// </summary>        /// <param name="args">参数</param>        void afteraction(object?[]? args);        /// <summary>        /// 执行之后        /// </summary>        /// <param name="args">参数</pa艺术论文ram>        /// <param name="result">结果</param>        void beforeaction(object?[]? args, object result);    }

2.3 定义aop特性

1.用来标记类具体使用哪个handle的实现来处理业务。

2. 特性定义type属性决定创建代理类的时候,具体使用哪个handle实现

[attributeusage(attributetargets.class)]    internal class interceptattribut : attribute    {        public type type { get; t; }        public interceptattribut(type type)         {            this.type = type;        }    }

2.4 定义创建代理类的工厂

这里就是来组装代理类与handle实现的地方。

internal class proxyfactory    {        /// <summary>        /// 创建代理实例        /// </summary>        /// <param name="decorated">代理的接口类型</param>        /// <returns></returns>        public static t create<t>()        {            var decorated = rvicehelp.getrvice<t>();            var type = decorated.gettype();            var interceptattribut = type.getcustomattribute<interceptattribut>();            var interceptor = rvicehelp.getrvice<iinterceptor>(interceptattribut.type);            //创建代理类            var proxy = new dynamicproxy<t>().create(decorated, interceptor.afteraction, interceptor.beforeaction);            return proxy;        }    }

1.拿到具体类,获取type,获取我们上面定义的特性,通过特性的属性,用来创建handle实例

2.rvicehelp是我定义的一个来获取实例化的容器帮助类。这个用.net core 原始的ioc。大家可替换成autofac

3.创建化代理实例,把实例和handle实现的具体方法:afteraction、beforeaction传入。用于代理美女摄影作品类执行的时候,进行真正的调用

2.5 定义rvicehelp

这里大家可自行发挥

public static class rvicehelp    {        public static irviceprovider? rviceprovider { get; t; }        public static void buildrviceprovider(irvicecollection rvicecollection)        {            //构建容器            rviceprovider = rvicecollection.buildrviceprovider();        }        public static t getrvice<t>(type rvicetype)        {            return (t)rviceprovider.getrvice(rvicetype);        }        public static t getrvice<t>()        {            return rviceprovider.getrvice<t>();        }    }

3.测试

3.1 定义handle实现

    internal class aoptest : iinterceptor    {        public void afteraction(object?[]? args)        {            console.writeline($"aop方法执行之前,args:{args}");            throw new exception("异常测试(异常,但依然不能影响程序执行)");        }        public void beforeaction(object?[]? args, object result)        {            console.w顺利的什么riteline($"aop方法执行之后,args:{args},result:{result}");        }    }

3.2 定义rvice接口

    internal interface itestrvice    {        public int add(int a, int b);    }

3.3实现rvice接口

定义实现,并且在类上加上,aop交给哪个handle

    [interceptattribut(typeof(aoptest))]    internal class testrvice : itestrvice    {        public int add(int a, int b)        {            console.writeline($"正在执行--》add({a},{b})");            throw new exception("方法执行--》测试异常");            return a + b;        }    }

3.4 大功告成

1.创建容器,把我们自己的业务实现都注册好

2.通过工厂进行,动态创建代理实例

// e https://aka.ms/new-console-template for more informationusing infrastructure.dynamicproxy;using microsoft.extensions.dependencyinjection;console.writeline("hello, world!");//容器注册irvicecollection rvicecollection = new rvicecollection();rvicecollection.addtransient(typeof(aoptest));rvicecollection.addtransient<itestrvice, testrvice>();//构建容器rvicehelp.buildrviceprovider(rvicecollection);//用工厂获取代理实例var s = proxyfactory.create<itestrvice>();var sum = s.add(1, 2);console.writeline("执行完毕=====>" + sum);

3.5 效果

4.demo

大家可直接访问我的,gitee

https://gitee.com/luoxiangbao/dynamic-proxy.git

以上就是.net core利用动态代理实现aop(面向切面编程)的详细内容,更多关于.net core实现aop的资料请关注www.887551.com其它相关文章!

本文发布于:2023-04-04 13:55:08,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/zuowen/86313cbc42014def8eaa468d98f90739.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

本文word下载地址:.NET Core利用动态代理实现AOP(面向切面编程).doc

本文 PDF 下载地址:.NET Core利用动态代理实现AOP(面向切面编程).pdf

标签:定义   方法   代码   实例
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图