.NET集成DeveloperSharp实现强大的AOP

这篇具有很好参考价值的文章主要介绍了.NET集成DeveloperSharp实现强大的AOP。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

(适用于.NET/.NET Core/.NET Framework)
【目录】
0.前言
1.第一个AOP程序
2.Aspect横切面编程
3.一个横切面程序拦截多个主程序
4.多个横切面程序拦截一个主程序
5.优势总结
6.展望


0.前言
AOP(Aspect Oriented Programming)是“面向横切面编程”,主要是用来对程序/模块进行解耦。怎么理解??

我们可以把一般的编程理解为“纵向编程”(主程序),比如如下的一个示例代码:

        public string GetInfo(int i)
        {
            string s = "";

            if (i == 1)
                s = "A";
            else if (i == 2)
                s = "B";
            else if (i == 3)
                s = "C";
            else
                s = "Z";

            return s;
        }

试想一下,上述软件实际使用后,

  • 如果条件变量i有更多的判断值,我们是不是要在GetInfo()方法内部修改代码+重新编译?
  • 如果后续需要加个日志记录功能,我们是不是也要在GetInfo()方法内部加上日志函数+重新编译?
  • 如果...
  • 更多如果...

为了避免上述的这些麻烦并增加软件的灵活性,“横向编程”,也就是AOP被创造了出来,它就像是“横切一刀”,把相关功能塞进了主程序。

 

现行AOP的实现,主要是通过拦截方法(即拦截主程序),并修改其参数+返回值来完成。

网上有很多相关方案,比如:特性注释拦截、动态代码生成、派遣代理模式、等。但这些方案要么实现的很复杂、要么耦合度没完全切断、逻辑有变化时还是需要修改少量代码重新编译。均不够理想

而今天要隆重登场的主角-DeveloperSharp平台中的AOP技术,则提供了一种简便、快捷、彻底解耦的AOP实现。使用它,在程序逻辑有变化时,你只需要修改配置文件就行,而不再需要对主程序进行一丁丁点的代码修改!!

(若遇到问题,需要技术支持??请添加微信:894988403)
(若遇到问题,需要技术支持??请添加微信:894988403)

1.第一个AOP程序

制作一个AOP程序需要四个步骤:

(1)制作主程序

(2)制作横切面程序

(3)制作配置文件,让横切面程序拦截主程序

(4)调用主程序

下面,我们一步一步来实现上述四个步骤。

【第一步】:制作主程序

我们在Visual Studio中新建一个名为“School.Logic”的类库工程,并在该工程中新建一个名为PersonManage的类,该类中有一个名为GetInfo1的方法,代码如下:

//从NuGet引用DeveloperSharp包
using DeveloperSharp.Structure.Model;

namespace School.Logic
{
    //主程序必须继承自LogicLayer类
    public class PersonManage : LogicLayer
    {
        public string GetInfo1(string Name, int Num)
        {
            return $"共有{Name}{Num}人";
        }
    }
}

以上,编写了一个非常简单的主程序。

 

【第二步】:制作横切面程序

我们再在Visual Studio中新建一个名为“School.Aspect”的类库工程,并在该工程中新建一个名为Interceptor1的类,代码如下:

//从NuGet引用DeveloperSharp包
using DeveloperSharp.Structure.Model.Aspect;

namespace School.Aspect
{
    //横切面程序必须继承自AspectModel类
    public class Interceptor1 : AspectModel
    {
        //PreProcess方法先于主程序执行
        public override void PreProcess(object sender, AspectEventArgs e)
        {
            //把主程序的两个参数值改掉
            e.MethodInfo.ParameterValues[0] = "老师";
            e.MethodInfo.ParameterValues[1] = 20;
        }

        //PostProcess方法后于主程序执行
        public override void PostProcess(object sender, AspectEventArgs e)
        {
            
        }
    }
}

 以上,编写了一个横切面程序。它的主要功能是把主程序方法的两个参数值给改掉。

 

【第三步】:制作配置文件,让横切面程序拦截主程序

若是在.Net Core环境下,我们创建一个名为DeveloperSharp.json的配置文件,设置让Interceptor1拦截PersonManage中的GetInfo1方法。文件内容如下:

{
  "DeveloperSharp":
  {
     "AspectObject":
     [
         {
           "name":"School.Aspect.Interceptor1",  //横切面拦截器类
           "scope":"School.Logic.PersonManage",  //被拦截的主程序类
           "method":"GetInfo1"                   //被拦截的方法
         }
     ]
  }
}

若是在.Net Framework环境下,我们创建一个名为DeveloperSharp.xml的配置文件,设置让Interceptor1拦截PersonManage中的GetInfo1方法。文件内容如下:

<?xml version="1.0" encoding="utf-8" ?>
<DeveloperSharp>
  <AspectObject>
    <Ao name="School.Aspect.Interceptor1" scope="School.Logic.PersonManage" method="GetInfo1"/>
  </AspectObject>
</DeveloperSharp>

注意:以上配置中所有的类名,都要用完全限定名。

 

【第四步】:调用主程序

最后,我们再在Visual Studio中创建一个控制台工程,让它来调用主程序中的GetInfo1方法,代码如下:

        //需要引用School.Aspect、School.Logic、DeveloperSharp三项
        static void Main(string[] args)
        {
            var pm = new School.Logic.PersonManage();

            //要用这种形式调用主程序中的方法,AOP功能才会生效
            var str = pm.InvokeMethod("GetInfo1", "学生", 200);
            Console.WriteLine(str);

            Console.ReadLine();
        }

为了让前面第三步创建的配置文件生效,我们此时还需要在此主调项目中对它进行链接:

若是在.Net Core环境下,我们只需要把DeveloperSharp.json文件放到程序执行目录中(即bin目录下与dll、exe等文件的同一目录中,放错了位置会报错)(注意:有些.Net Core版本在Visual Studio“调试”时,不会在bin目录下生成全部的dll、exe,此时需要把此配置文件放在应用程序的“根目录”下)。
若是在.Net Framework环境下,我们需要在工程配置文件App.config/Web.config中添加appSettings节点,节点内容如下:

  <appSettings>
    <add key="ConfigFile" value="D:\Test\Assist\DeveloperSharp.xml" />
  </appSettings>

此处需要设置为配置文件的“绝对路径”(使用“绝对路径”而不是“相对路径”,一是有利于安全性,二是有利于分布式部署)

 

一切准备完毕,运行,结果如下:

【控制台显示出】:共有老师20人

可见AOP已经拦截成功。

若此时,我们在配置文件DeveloperSharp.json/DeveloperSharp.xml中稍做修改,比如:把“GetInfo1”这个方法名改为“ABC”这样一个不存在的方法名,再运行,结果如下:

【控制台显示出】:共有学生200人

 

注意:使用DeveloperSharp平台的AOP技术,主程序类库名必须以Logic结尾(本篇为:School.Logic),横切面程序类库名必须以Aspect结尾(本篇为:School.Aspect),且这两个名字的其它部分要完全一样。这是一个特别限定条件!

 

2.Aspect横切面编程

上面,第二步,制作的横切面程序,是通过修改主程序方法的参数值,而最终改变了主程序的返回值。

其实,我们也有办法直接修改主程序方法的返回值,比如把上面Interceptor1类的代码修改为如下:

//从NuGet引用DeveloperSharp包
using DeveloperSharp.Structure.Model.Aspect;

namespace School.Aspect
{
    //横切面程序必须继承自AspectModel类
    public class Interceptor1 : AspectModel
    {
        //PreProcess方法先于主程序执行
        public override void PreProcess(object sender, AspectEventArgs e)
        {

        }

        //PostProcess方法后于主程序执行
        public override void PostProcess(object sender, AspectEventArgs e)
        {
            //把主程序的返回值改掉
            e.MethodInfo.ReturnValue = $"共有校长2人";
        }
    }
}

运行,结果如下:

【控制台显示出】:共有校长2人

 

到目前为止,我们已经知道了如何通过“Aspect横切面程序”修改主程序方法的参数值、返回值。

如果我们想进一步获取主程序的“命名空间”、“类名”、“方法名”、“参数名”、“参数类型”、“返回值类型”,则可以通过如下代码获取:

e.MethodInfo.NamespaceName                       //命名空间
e.MethodInfo.ClassName                           //类名
e.MethodInfo.MethodName                          //方法名
e.MethodInfo.ParameterInfos[0].Name              //参数名(第一个参数)
e.MethodInfo.ParameterInfos[0].ParameterType     //参数类型(第一个参数)
e.MethodInfo.ReturnValue.GetType()               //返回值类型

 

有时候,在某些特殊情况下,我们希望主程序方法不运行,此时则可以通过在PreProcess方法里把e.Continue设置为false来完成。

接前面的“第一个AOP程序”,比如:我们希望当人数大于10000时,主程序方法就不再运行,则可以通过把Interceptor1类的代码修改为如下样式来实现:

//从NuGet引用DeveloperSharp包
using DeveloperSharp.Structure.Model.Aspect;

namespace School.Aspect
{
    //横切面程序必须继承自AspectModel类
    public class Interceptor1 : AspectModel
    {
        //PreProcess方法先于主程序执行
        public override void PreProcess(object sender, AspectEventArgs e)
        {
            //当人数大于10000时,主程序方法就不再运行
            if (Convert.ToInt32(e.MethodInfo.ParameterValues[1]) > 10000)
                e.Continue = false;
        }

        //PostProcess方法后于主程序执行
        public override void PostProcess(object sender, AspectEventArgs e)
        {

        }
    }
}

现在的这个示例是一个Aspect横切面程序拦截一个主程序。在后续将要讲解的“多个Aspect横切面程序拦截一个主程序”的情况中,只要有一个e.Continue=false被设置,主程序方法就不会运行(在此事先提点)。

 

3.一个横切面程序拦截多个主程序

为了演示这部分的内容,我们首先在前面“第一个AOP程序”的基础上,把主程序进行扩充。采取的动作是:

(1)在PersonManage类中增加一个GetInfo2方法

(2)再新增一个主程序类SystemManage,该类中有一个名为GetMessage1的方法。代码如下:

PersonManage类:

//从NuGet引用DeveloperSharp包
using DeveloperSharp.Structure.Model;

namespace School.Logic
{
    //主程序必须继承自LogicLayer类
    public class PersonManage : LogicLayer
    {
        public string GetInfo1(string Name, int Num)
        {
            return $"共有{Name}{Num}人";
        }

        public string GetInfo2(string Name, int Num)
        {
            return $"学校共有{Name}{Num}人";
        }
    }
}

SystemManage类:

//从NuGet引用DeveloperSharp包
using DeveloperSharp.Structure.Model;

namespace School.Logic
{
    //主程序必须继承自LogicLayer类
    public class SystemManage : LogicLayer
    {
        public string GetMessage1(string Name1, int Num1, string Name2, int Num2)
        {
            return $"第一组共有{Name1}{Num1}人,第二组共有{Name2}{Num2}人";
        }
    }
}

如此一来,现在就有了3个主程序方法。

 

接下来,我们修改配置文件,让Interceptor1去拦截上述的3个主程序方法。

若是在.Net Core环境下,DeveloperSharp.json文件的内容修改为如下:

{
  "DeveloperSharp":
  {
     "AspectObject":
     [
         {
           "name":"School.Aspect.Interceptor1", 
           "scope":"School.Logic.PersonManage",
           "method":"*"   //星号*代表该作用域下的全部方法
         },
         {
           "name":"School.Aspect.Interceptor1", 
           "scope":"School.Logic.SystemManage",
           "method":"GetMessage1"
         }
     ]
  }
}

若是在.Net Framework环境下,DeveloperSharp.xml文件的内容修改为如下:

<?xml version="1.0" encoding="utf-8" ?>
<DeveloperSharp>
  <AspectObject>
    <Ao name="School.Aspect.Interceptor1" scope="School.Logic.PersonManage" method="*"/>
    <Ao name="School.Aspect.Interceptor1" scope="School.Logic.SystemManage" method="GetMessage1"/>
  </AspectObject>
</DeveloperSharp>

 

 最后,我们把控制台启动程序修改为如下:

        //需要引用School.Aspect、School.Logic、DeveloperSharp三项
        static void Main(string[] args)
        {
            var pm = new School.Logic.PersonManage();
            var sm = new School.Logic.SystemManage();

            //要用这种形式调用主程序中的方法,AOP功能才会生效
            var str1 = pm.InvokeMethod("GetInfo1", "学生", 200);
            var str2 = pm.InvokeMethod("GetInfo2", "学生", 200);
            var str3 = sm.InvokeMethod("GetMessage1", "学生", 200, "院士", 10);
            Console.WriteLine(str1);
            Console.WriteLine(str2);
            Console.WriteLine(str3);

            Console.ReadLine();
        }

运行结果如下:

【控制台显示出】:

共有老师20人
学校共有老师20人
第一组共有老师20人,第二组共有院士10人

可见AOP所有拦截均已成功!

 

4.多个横切面程序拦截一个主程序

为了演示这部分的内容,我们还是要先回到前面的“第一个AOP程序”,在它的基础上,我们新增一个名为Interceptor2的Aspect横切面类,代码如下:

//从NuGet引用DeveloperSharp包
using DeveloperSharp.Structure.Model.Aspect;

namespace School.Aspect
{
    //横切面程序必须继承自AspectModel类
    public class Interceptor2 : AspectModel
    {
        //PreProcess方法先于主程序执行
        public override void PreProcess(object sender, AspectEventArgs e)
        {
            //把主程序的两个参数值改掉
            e.MethodInfo.ParameterValues[0] = "辅导员";
            e.MethodInfo.ParameterValues[1] = 40;
        }

        //PostProcess方法后于主程序执行
        public override void PostProcess(object sender, AspectEventArgs e)
        {

        }
    }
}

如此一来,我们就有了2个Aspect横切面程序Interceptor1与Interceptor2。

 

接下来,我们修改配置文件,让Interceptor1、Interceptor2都去拦截主程序方法GetInfo1。

若是在.Net Core环境下,DeveloperSharp.json文件的内容修改为如下:

{
  "DeveloperSharp":
  {
     "AspectObject":
     [
         {
           "name":"School.Aspect.Interceptor1", 
           "scope":"School.Logic.PersonManage",
           "method":"GetInfo1"
         },
         {
           "name":"School.Aspect.Interceptor2", 
           "scope":"School.Logic.PersonManage",
           "method":"GetInfo1"
         }
     ]
  }
}

若是在.Net Framework环境下,DeveloperSharp.xml文件的内容修改为如下:

<?xml version="1.0" encoding="utf-8" ?>
<DeveloperSharp>
  <AspectObject>
    <Ao name="School.Aspect.Interceptor1" scope="School.Logic.PersonManage" method="GetInfo1"/>
    <Ao name="School.Aspect.Interceptor2" scope="School.Logic.PersonManage" method="GetInfo1"/>
  </AspectObject>
</DeveloperSharp>

 

上述修改完毕,运行控制台主调程序,结果如下:

【控制台显示出】:共有辅导员40人

从上述运行结果,我们大致可以推断出:Interceptor1、Interceptor2这两个Aspect横切面拦截器是按配置顺序执行的。其中,Interceptor1先把GetInfo1方法的两个参数值改为了("老师",20),接着,Interceptor2又把GetInfo1方法的两个参数值改为了("辅导员",40),所以最终GetInfo1方法的参数值变为了("辅导员",40)。

 

5.优势总结

本文所讲述的,是全网唯一实现AOP彻底解耦的技术方案。使用它,当你需要给主程序增加Aspect横切面拦截器时,无论是增加一个还是多个,都不再需要修改&重新编译主程序。这实现了不同功能构件之间的0依赖拼装/拆卸开发方式,随之而来的也会对研发团队的管理模式产生重大影响,意义深远...

 

6.展望

AOP对于程序代码的解耦、业务模块的拆分与拼装组合,有着巨大的作用。正确的使用AOP,甚至能对传统的软件架构设计,产生颠覆性的影响,如超级战士出场一般,让所有人刮目相看,完全耳目一新!!

为了让读者能直观感知AOP的上述神奇魅力,下面给出一个业务案例:
有一批货品要录入数据库,货品包含长、宽、高、颜色、类型等属性。现在有业务需求如下,
(1)当货品长度大于10厘米时,它在数据库中标记为A类;当货品长度大于20厘米时,标记为B类。
(2)当货品颜色无法分辨时,统一在数据库中默认标记为白色。
(3)每个货品录入数据库后,还要在另一个财务数据库中录入该货品的价格信息,同时把该货品的操作员名字记入日志文件。

这样的一个业务案例,你以前会怎么设计这个程序?今天学了AOP后你又会怎么设计程序?你会创建几个Aspect横切面了...?

 


原文首发于下方公众号,请关注!

向大佬学习,探行业内幕,享时代机遇。

.NET集成DeveloperSharp实现强大的AOP文章来源地址https://www.toymoban.com/news/detail-839321.html

到了这里,关于.NET集成DeveloperSharp实现强大的AOP的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 在net中通过Autofac实现AOP的方法及实例详解

      在本示例中,我们将使用Autofac和AspectC( Autofac.Extras.DynamicProxy2)来演示如何实现AOP(面向切面编程)。我们将创建一个简单的C#控制台应用程序,并应用AOP以解决日志记录的问题。首先,让我们讨论AOP的用途和目标。 AOP是一种编程范式,旨在解决横切关注点(cross-cutting

    2024年02月05日
    浏览(28)
  • c# .net framework 实现微信支付v3 h5支付 签名 验签

    接口文档:微信支付-开发者文档 (qq.com)    遇到的问题有   1、签名老验证不过去 :      生成的签名老验证不过    n 不要加转义符   2、 发送的请求老是400  使用工具请求正常。代码不行。   UserAgent = \\\"m.cnblogs.com/WebRequest\\\";    不要留空就行 网址可填自己的

    2024年02月05日
    浏览(32)
  • Spring FrameWork从入门到NB - Spring AOP - 概念

    什么是AOP AOP - Aspect Oriented Programming的缩写,面向切面编程。 面向切面编程AOP是面向对象程序设计OOP的一个补充或扩展,是为了解决OOP在一些共性问题上的不足应运而生的。比如记录日志、事务处理、性能分析等等与业务无关的需求,需要发生在很多类的很多方法上,而需求

    2024年02月13日
    浏览(24)
  • Spring AOP使用指南: 强大的面向切面编程技术

    🌷🍁 博主猫头虎(🐅🐾)带您 Go to New World✨🍁 🦄 博客首页 ——🐅🐾猫头虎的博客🎐 🐳 《面试题大全专栏》 🦕 文章图文并茂🦖生动形象🐅简单易学!欢迎大家来踩踩~🌺 🌊 《IDEA开发秘籍专栏》 🐾 学会IDEA常用操作,工作效率翻倍~💐 🌊 《100天精通Golang(基础

    2024年02月09日
    浏览(34)
  • VR Interaction Framework2.0插件的使用(适用于Pico串流)

            随着Pico被字节收购,追踪优化变好了,Pico的串流也越来越好用了,现在已经可以用于开发了,现在所用的设备为Pico Neo3消费版,个人感觉的使用感受是,比起上万的HTC Vive设备,几千的Pico Neo3消费版,某种程度来说是更加好用的,现在我要介绍的VR开发框架为VR

    2024年02月16日
    浏览(37)
  • JFrog推出面向Hugging Face的原生集成,为 ML 模型提供强大支持,实现DevOps、安全和AI的协调统一

    2023年12月5日 —— 流式软件公司、企业软件供应链平台提供商JFrog推出ML模型管理功能,这是业界首套旨在简化机器学习(ML)模型管理和安全性的功能。JFrog 平台中的全新ML模型管理功能使AI交付与企业现有的 DevOps 和 DevSecOps 实践保持一致,从而加速、保护和管理ML组件的发布

    2024年02月04日
    浏览(31)
  • 关于MSMQ(System.Messaging.MessageQueue)安装及在.NET Framework框架下的简单应用实现,以解决大并发请求问题

    提示:大并发请求队列处理及实时聊天消息也可参考本文自行实现 随着大数据的不断发展,我们实际开发的项目也开始逐渐接触到大数据大并发造成的一些问题,由于近期项目需求要满足2000并发量,经过压测发现原项目中编写的正常逻辑读写程序很卡顿,服务器环境Windows

    2024年02月06日
    浏览(30)
  • .NET Framework 4.5升级到 .NET Framework 4.8.x

     .NET Framework 4.5升级到.NET Framework 4.8.x的步骤分享如下: 1.下载并安装 .NET Framework 4.8.x 从 Microsoft 的官方网站上下载 .NET Framework 4.8.x 的安装程序,并按照提示安装。在安装过程中,可以选择是否安装语言包和参考源代码。 2.更新现有应用程序 完成 .NET Framework 4.8.x 的安装后,需

    2024年02月04日
    浏览(33)
  • VS2022 安装 .NET Framework 4.0 和 .NET Framework 4.5 的方法

    2022年5月27日,刚刚把VS2019升级到了VS2022,安装时已经不提供.NET Framework 4.0和.NET Framework 4.5的目标框架了,打开VS也提示不支持目标框架。 1、下载.NET Framework框架 .NET Framework 4.5.2 .NET Framework 4.5.1 .NET Framework 4.5 .NET Framework 4.0 备份链接:https://pan.baidu.com/s/1AIuva6GjGGKQ2XJftZpIyQ 提取码

    2024年02月12日
    浏览(36)
  • VS2022 安装 .NET Framework 4.0或.NET Framework 4.5 以及其他版本

    VS2019升级到了VS2022之后,安装时已经不提供.NET Framework 4.0和.NET Framework 4.5的目标框架了,打开VS也提示不支持目标框架。 下载.NET Framework框架 官网下载对应版本的sdk:https://dotnet.microsoft.com/zh-cn/download/visual-studio-sdks?cid=getdotnetsdk 点击开发者工具包进行下载; 下载完之后直接双

    2024年02月11日
    浏览(28)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包