专栏首页林德熙的博客dotnet core 2 使用 DispatchProxy 做动态代理 AOP 入门

dotnet core 2 使用 DispatchProxy 做动态代理 AOP 入门

本文简单告诉大家如何在 .NET Core 里面使用 AOP 切面编程,使用 DispatchProxy 做任意接口的动态代理实现

使用 DispatchProxy 有一些限制,如只能创建接口的实例。使用 DispatchProxy 可以让咱做到从无中创建出某个实例,这个实例继承咱想要的接口

首先需要创建某个动态代理类继承 DispatchProxy 类,例如创建 Foo 类。此时需要实现 Invoke 接口,这个接口的含义是当代码调用接口里面的函数,包括属性的设置和获取函数的时候将会进入 Invoke 方法

        protected override object Invoke(MethodInfo targetMethod, object[] args)
        {
            // 忽略代码
        }

因此通过 Invoke 方法可以假装自己是对应的接口的实现,可以进行随意更改执行逻辑以及修改返回值

而 DispatchProxy 另一个核心方法是静态的 Create 方法,这个方法要求传入两个泛形,第一个类型是想要创建出来的实例继承的接口,第二个类型是某个继承 DispatchProxy 的类

例如咱定义了一个 IF1 的接口,此时可以在 Foo 添加如下代码创建出一个不存在的类型实例,这个实例继承了 IF1 接口

    public class Foo : DispatchProxy
    {
        public static T GetObject<T>()
        {
            return DispatchProxy.Create<T, Foo>();
        }

        protected override object Invoke(MethodInfo targetMethod, object[] args)
        {
            return "lindexi";
        }
    }

假设 IF1 的定义如下

    interface IF1
    {
        string F2();
    }

此时的使用方法如下

            Console.WriteLine(Foo.GetObject<IF1>().F2());

执行代码可以看到输出了 lindexi 也就是实际调用了 Foo 方法

可以看到 DispatchProxy 的作用就是提供静态方法用于创建继承指定接口的对象,同时让继承 DispatchProxy 的类可以拿到接口所调用的方法,用来修改执行逻辑和返回值

一个实际的使用的例子,提供了调用某个对象的每个方法之前给这个对象调用方法记日志,这是最简便的记日志的方法了,尽管性能很渣

    public class LoggingAdvice<T> : DispatchProxy
    {
        private T Object { set; get; }


        public static T CreateLogging(Func<T> creator)
        {
            object proxy = DispatchProxy.Create<T, LoggingAdvice<T>>();
            ((LoggingAdvice<T>)proxy).Object = creator();
            return (T)proxy;
        }

        protected override object Invoke(MethodInfo targetMethod, object[] args)
        {
            Console.WriteLine($"开始执行 {targetMethod.Name}");

            var result = targetMethod.Invoke(Object, args);

            Console.WriteLine($"执行完成 {targetMethod.Name}");

            return result;
        }
    }

此时就能做到在方法执行前后添加日志,如这里有一个接口和一个类,使用方法请参考以下示例

    class Program
    {
        static void Main(string[] args)
        {
            var foo = LoggingAdvice<IF1>.CreateLogging(() => new Foo());
            foo.F2();
        }
    }

    interface IF1
    {
        string F2();
    }

    class Foo : IF1
    {
        /// <inheritdoc />
        public string F2()
        {
            return "lindexi";
        }
    }

参考

在.NET Core中使用DispatchProxy“实现”非公开的接口 - LamondLu - 博客园

使用.net core中的类DispatchProxy实现AOP - 欧阳.NET - 博客园

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • dotnet 代码调试方法

    本文将会从简单到高级,告诉大家如何调试 dotnet 的代码,特别是桌面端。本文将会使用到 VisualStudio 大量的功能,通过各种好用的功能提高调试方法

    林德熙
  • WPF 客户端开发需要知道的触摸失效问题

    在说 WPF 开发的时候,如果开发的应用是触摸应用,那么熟悉的小伙伴会说到触摸失效问题。从分类上触摸失效有系统的触摸失效,应用程序的触摸失效,同时触摸失效指的不...

    林德熙
  • 图论 Warshall 和Floyd 矩阵传递闭包

    我们来说下有向图,一般的有向图也是图,图可以分为稠密图,稀疏图,那么从意思上,稠密图就是点的边比较多,稀疏图就是边比较少的图。为什么稠密图放在矩阵比较省空间,因...

    林德熙
  • 深入理解设计模式六大原则

    万变不离其宗,不管是Java还是C++,凡是面向对象的编程语言,在设计上,尽管表现形式可能有所不同,但是其实质和所需遵守的原则都是一致的。本文便是带领读者去深入...

    王金龙
  • 来自前端同学对后端童鞋的吐槽!@!#^$%

    去年的某个时候就想写一篇关于接口的吐槽,当时后端提出了接口方案对于我来说调用起来非常难受,但又说不上为什么,没有论点论据所以也就作罢。最近因为写全栈的缘故,团队...

    Java小咖秀
  • 有理有据:一篇来自前端同学对后端接口的吐槽!

    来源 | juejin.im/post/5cfbe8c7e51d4556da53d07f

    程序猿DD
  • 大话性能测试系列(3)- 常用的性能指标

    https://www.cnblogs.com/poloyy/category/1620792.html

    小菠萝测试笔记
  • miniblink重新开更啦

    惭愧,很长时间没发文章了,其实miniblink自从上月起就一直在频繁更新了,但一直懒得写文章记录下来。

    龙泉寺扫地僧
  • app端接口用例设计方法和测试方法(一)

    接口测试用例结构要符合实际请求和下发的数据结构,这样方便了解数据结构特点,快速掌握接口数据含义,熟悉接口业务。先介绍请求数据的用例结构

    用户5521279
  • 快速学习-接口文档

    将admin/controller/Goods.php中 save方法 改为 接口方式

    cwl_java

扫码关注云+社区

领取腾讯云代金券