0

0

在.NET项目中使用PostSharp

PHPz

PHPz

发布时间:2017-03-12 15:48:55

|

5312人浏览过

|

来源于php中文网

原创

postsharp是一种aspect oriented programming 面向切面(或面向方面)的组件框架,适用在.net开发中,本篇主要介绍postsharp在.net开发中的相关知识,以及一些如日志、缓存、事务处理、异常处理等常用的切面处理操作。

AOP(Aspect-Oriented Programming)是一种将函数的辅助性功能与业务逻辑相分离的编程泛型(programming paradigm),其目的是将横切关注点(cross-cutting concerns)分离出来,使得程序具有更高的模块化特性。AOP是面向方面软件开发(Aspect-Oriented Software Development)在编码实现层面上的具体表现。

我们知道,解耦是程序员编码开发过程中一直追求的,AOP也是为了解耦所诞生。引入AOP技术,能很大程度上简化我们编码,减少复制的代码量,也便于统一维护统一的部分代码,如日志、缓存、事务处理、异常处理等常用的处理。

1、AOP框架的介绍

1)AOP技术介绍

AOP技术利用一种称为“横切”的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其名为“Aspect”,即方面。所谓“方面”,简单地说,就是将那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可操作性和可维护性。AOP代表的是一个横向的关系,如果说“对象”是一个空心的圆柱体,其中封装的是对象的框架0和行为;那么面向方面编程的方法,就仿佛一把利刃,将这些空心圆柱体剖开,以获得其内部的消息。而剖开的切面,也就是所谓的“方面”了。然后它又以巧夺天功的妙手将这些剖开的切面复原,不留痕迹。

使用“横切”技术,AOP把软件系统分为两个部分:核心关注点和横切关注点。业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点。横切关注点的一个特点是,他们经常发生在核心关注点的多处,而各处都基本相似。比如权限认证、日志、事务处理。Aop 的作用在于分离系统中的各种关注点,将核心关注点和横切关注点分离开来。正如Avanade公司的高级方案构架师Adam Magee所说,AOP的核心思想就是“将框架1程序中的商业逻辑同对其提供支持的通用框架2进行分离。”

 

2)AOP使用场景

AOP用来封装横切关注点,具体可以在下面的场景中使用:

Authentication 权限

Caching 缓存

Context passing 内容传递

Error han框架3ing 框架4

Lazy loading 懒加载

Debugging  框架5

logging, tracing, profiling and monitoring 记录跟踪 优化 校准

Per框架6mance optimization 框架7

Persistence  持久化

框架8 pooling 资源池

Syn框架9onization 同步

Trans介绍0s 事务

 

3)PostSharp框架

PostSharp是一个用于在.NET平台上实现AOP的框架,是比较常用的一个AOP框架,官方网站为http://www.php.cn/。目前最新版本为4.X,但是是收费的AOP软件。

PostSharp使用介绍1织入方式实现AOP,其连接点非常丰富,使用简单,而且相对介绍2一些.NET平台上的AOP框架来说,PostSharp较为轻量级,但是功能却一点也不逊色。

总体来说,使用PostSharp,将会带来如下优点:

  • 横切关注点单独分离出来,提高了代码的清晰性和可维护性。

  • 只要在Aspect中编写辅助性功能代码,在一定程度上减少了工作量和冗余代码。

当然,使用PostSharp也会存在一些缺点,主要缺点有如下两方面:

  • 增加了调试的难度。

    eshop网上书店源码
    eshop网上书店源码

    适合初学的标准三层架构,采用ajax,页面布局div+css符合w3c,用vs自带的sqlserver,免配置sqlserver,使用方便,里面共有5个项目,点击最外层的.sln直接可运行。网站采用asp.net 用户角色配置(membership,UserRoles),用户角色、权限可在asp.net配置里修改,注册,登陆均采用asp.net登陆控件,网站根据用户角色自定义sitemap,基本上

    下载
  • 相比于不用AOP的代码,运行效率有所降低。

不过瑕不掩瑜,相对于这些缺点问题,使用PostSharp可以极大提高开发效率,减少重复代码,从而提高代码的可读性、可维护性。

另外在介绍3Hub上还有一些开源的AOP组件,例如排头位的是KingAOP(http://www.php.cn/),不过由于它采用了Dynamic的方式来实现,如它的构造对象如下所示。


dynamic helloWorld = new HelloWorld();
helloWorld.HelloWorldCall();

因此虽然比较方便,而且号称和PostSharp使用习惯类似,但是改变了对象的创建方式,对一般项目的类对象处理并不太适合。因此我还是比较倾向于使用PostSharp来进行AOP的编程开发。

 

2、PostSharp框架的使用

1)准备PostSharp的编译环境

PostSharp目前版本是4.x,我在官网下载了进行使用,不过经常发生"Error connecting to the pipe server. See 介绍4ious warnings for details.",后来干脆使用了3.x版本的,反而能够正常使用,非常不错,呵呵。

PostSharp是一个可以介绍5在VS上的插件,安装后在VS的菜单栏目里面增加了一个PostSharp的菜单项,如下所示。

一般项目如果需要使用PostSharp特性的,在项目属性的【PostSharp】选项页中,使用【Add PostSharp to this project】把PostSharp加入到项目里面进行使用。

 添加后,会弹出PostSharp的插件提示对话框,提示将加入相应的PostSharp包等内容,如下所示。

完成后就可以在项目中使用PostSharp的相关类了。

 

2)增加PostSharp的AOP切面处理

一般约定每个Aspect类的命名必须为“XXXAttribute”的形式。其中“XXX”就是这个Aspect的名字。PostSharp中提供了丰富的内置“Base Aspect”以便我们介绍6,其中这里我们继承“OnMethodBoundaryAspect ”,这个Aspect提供了进入、介绍7函数等连接点方法。另外,Aspect上必须设置“[Serializable] ”,这与PostSharp内部对Aspect的介绍8管理有关。

日志的Aspect类的代码如下所示。


    [Serializable]    public class LogAttribute : OnMethodBoundaryAspect
    {        public override void OnEntry(MethodExecutionArgs args)
        {
            Console.WriteLine(Environment.NewLine);

            Console.WriteLine("Entering [ {0} ] ...", args.Method);            base.OnEntry(args);
        }        public override void OnExit(MethodExecutionArgs args)
        {
            Console.WriteLine("Leaving [ {0} ] ...", args.Method);            base.OnExit(args);
        }
    }

异常处理的类代码如下所示。


    [Serializable]    public class ExceptionAttribute : OnExceptionAspect
    {        public override void OnException(MethodExecutionArgs args)
        {
            Console.WriteLine(String.Format("Exception in :[{0}] , Message:[{1}]", args.Method, args.Exception.Message));
            args.FlowBehavior = FlowBehavior.Continue;            base.OnException(args);
        }
    }

计时处理的Aspect类代码如下所示。


    [Serializable]
    [MulticastAttributeUsage(MulticastTargets.Method)]    public class TimingAttribute : PostSharp.Aspects.OnMethodBoundaryAspect
    {
        [NonSerialized]
        Stopwatch _StopWatch;        public override void OnEntry(PostSharp.Aspects.MethodExecutionArgs args)
        {
            _StopWatch = Stopwatch.StartNew();            base.OnEntry(args);
        }        public override void OnExit(PostSharp.Aspects.MethodExecutionArgs args)
        {
            Console.WriteLine(string.Format("[{0}] took {1}ms to execute",              new StackTrace().GetFrame(1).GetMethod().Name,
                _StopWatch.ElapsedMilliseconds));            base.OnExit(args);
        }
    }

事务处理的Aspect类代码如下所示。


    [Serializable]
    [AspectTypeDependency(AspectDependencyAction.Order, AspectDependencyPosition.After, typeof(LogAttribute))]    public class RunInTransactionAttribute : OnMethodBoundaryAspect
    {
        [NonSerialized]
        TransactionScope TransactionScope;        public override void OnEntry(MethodExecutionArgs args)
        {            this.TransactionScope = new TransactionScope(TransactionScopeOption.RequiresNew);
        }        public override void OnSuccess(MethodExecutionArgs args)
        {            this.TransactionScope.Complete();
        }        public override void OnException(MethodExecutionArgs args)
        {
            args.FlowBehavior = FlowBehavior.Continue;
            Transaction.Current.Rollback();
            Console.WriteLine("Transaction Was Unsuccessful!");
        }        public override void OnExit(MethodExecutionArgs args)
        {            this.TransactionScope.Dispose();
        }
    }

下面是几个Aspect类的切面处理代码,如下所示。


        [Exception]
        [Log]        static void Calc()
        {            throw new pideByZeroException("A Math Error Occured...");
        }

        [Log, Timing]        static void LongRunningCalc()
        {            //wait for 1000 miliseconds
            Thread.Sleep(1000);
        }

从上面我们可以看到,常规的异常处理、日志处理都已经通过Attribute的方式进行处理了,在函数体里面都只是剩下具体的业务逻辑代码了,这样极大提高了代码的可读性,简洁明了。

运行上面的代码函数的调用,我们可以在输出日志里面看到具体的结果内容。


Entering [ Void Calc() ] ...
“System.pideByZeroException”类型的第一次机会异常在 PostSharpExample.exe 中发生
Exception in :[Void Calc()] , Message:[A Math Error Occured...]
Leaving [ Void Calc() ] ...


Entering [ Void LongRunningCalc() ] ...
Leaving [ Void LongRunningCalc() ] ...
[LongRunningCalc] took 1002ms to execute

这样,通过声明的方式,就实现了常规日志 、异常的处理,当然实际项目上使用日志、异常处理的这些代码肯定会更加复杂一些,不过小例子已经实现了切面逻辑的分离处理了,尘归尘、土归土,一切都是那么的简洁安静了。

 

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
go语言 注释编码
go语言 注释编码

本专题整合了go语言注释、注释规范等等内容,阅读专题下面的文章了解更多详细内容。

2

2026.01.31

go语言 math包
go语言 math包

本专题整合了go语言math包相关内容,阅读专题下面的文章了解更多详细内容。

1

2026.01.31

go语言输入函数
go语言输入函数

本专题整合了go语言输入相关教程内容,阅读专题下面的文章了解更多详细内容。

1

2026.01.31

golang 循环遍历
golang 循环遍历

本专题整合了golang循环遍历相关教程,阅读专题下面的文章了解更多详细内容。

0

2026.01.31

Golang人工智能合集
Golang人工智能合集

本专题整合了Golang人工智能相关内容,阅读专题下面的文章了解更多详细内容。

1

2026.01.31

2026赚钱平台入口大全
2026赚钱平台入口大全

2026年最新赚钱平台入口汇总,涵盖任务众包、内容创作、电商运营、技能变现等多类正规渠道,助你轻松开启副业增收之路。阅读专题下面的文章了解更多详细内容。

76

2026.01.31

高干文在线阅读网站大全
高干文在线阅读网站大全

汇集热门1v1高干文免费阅读资源,涵盖都市言情、京味大院、军旅高干等经典题材,情节紧凑、人物鲜明。阅读专题下面的文章了解更多详细内容。

73

2026.01.31

无需付费的漫画app大全
无需付费的漫画app大全

想找真正免费又无套路的漫画App?本合集精选多款永久免费、资源丰富、无广告干扰的优质漫画应用,涵盖国漫、日漫、韩漫及经典老番,满足各类阅读需求。阅读专题下面的文章了解更多详细内容。

67

2026.01.31

漫画免费在线观看地址大全
漫画免费在线观看地址大全

想找免费又资源丰富的漫画网站?本合集精选2025-2026年热门平台,涵盖国漫、日漫、韩漫等多类型作品,支持高清流畅阅读与离线缓存。阅读专题下面的文章了解更多详细内容。

19

2026.01.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C# 教程
C# 教程

共94课时 | 8.2万人学习

python编程入门系列图文教程
python编程入门系列图文教程

共65课时 | 24.7万人学习

vscode其实很简单
vscode其实很简单

共72课时 | 29.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号