zoukankan      html  css  js  c++  java
  • .net postsharp编译时生成的代码?

     

    使用PostSharp进行AOP框架设计:一个简单的原型

     

     

     

    AOP已经不是一个什么新名词了,在博客园使用关键字搜索可以查出n多条关于AOP的介绍,这里就不再赘述了。

    Bruce Zhang's Blog里面有很多关于AOP介绍及其在.net下实现研究,总觉得如果什么都从头来写难免有自造轮子的嫌疑,但是目前也没有很成熟的AOP框架让我们能轻松完成基于AOP架构,不过一直以来都在关注的PostSharp开源项目日趋成熟,目前已发布了PostSharp 1.0 (Beta release 3)。即使如此,也还没能到应用到产品上的时候。

    前段时间一直在封装一个权限系统,时常为如何给调用方提供一个良好的编程接口烦恼,加之前前段时间考虑的日志、异常接管、事务、缓存等等一些横向组件的架构分析,自然就想用AOP技术实现,但是由于实现难度实在不小作罢;这两天又重新学习研究了PostSharp的架构与实现思想,觉得还是尝试一下,将其融入现有框架;

    早在年初就有不少前辈大师就如何使用这个东西撰写过文章,如Q.yuhenPostSharp - Lightweight Aspect-Oriented System该仁兄下面见解很到位:

    和以往基于 Dynamic Proxy 方式与 AOP 解决方案做个比较。

    • 由于采用 MSIL Injection,因此静态代码注入的执行效率要高于使用 Reflection Emit。
    • 使用 MSBuild Task,使得开发人员可以像使用编译器内置 Attribute 那样使用 AOP。
    • 可以拦截任意方法,而 Dynamic Proxy 方式的 AOP 往往采取继承方式来拦截 Virtual 方法。
    • 拥有更多的控制权。包括中断执行流程,修改参数和返回值等等。
    • 还可以拦截 Field Access、Exception 等操作。
    • 无需将对象创建代码改成 "new proxy()",更加透明。
    • 可以使用通配符进行多重拦截匹配。
    • 静态注入带来的问题更多的是注入代码的质量和调试复杂度。

    另外有一老外的Using AOP and PostSharp to Enhance Your CodeAB两部分,相当精彩,本文就是在参考这两篇好文的基础上做的。

    我们假设有这么个场景,其实这也是实际业务中很常见的处理方式:有一定单管理模块,具备新增、删除两功能,我们在新增删除的时候必须校验权限,在删除的时候还必须记录日志,出现异常了还必须捕捉并记录异常;

    按以前的写法我们可能很麻烦,我们要如此这般的写: 

    public class Orders
        {
            
    public bool Add(string id, string orderName)
            {
                
    try
                {
                    
    if (User.AddEnable)
                    {
                        
    //TODO:新增订单的实现
                        Console.WriteLine("正在执行新增订单方法的操作,回车继续……");
                        Console.ReadLine();
                        Console.WriteLine(
    "您添加订单成功:编号:{0},名称:{1}", id, orderName);
                        
    return true;
                    }
                    
    else
                    {
                        
    //
                    }
                }
                
    catch (Exception)
                {
                    
    //TODO:记录异常的实现
                    throw;
                }

                
    return true;

            }

            
    public bool Delete(string id)
            {
                
    try
                {
                    
    if (User.DeleteEnable)
                    {
                        
    //TODO:删除订单的实现
                        Console.WriteLine("您删除订单成功:编号:{0}", id);
                    }
                    
    else
                    {
                        
    //
                    }

                }
                
    catch (Exception)
                {
                    
    //TODO:记录异常的实现
                    throw;
                }

                
    return true;
            } 

    这种写的弊端我就不多说了,有很多先驱都阐述过……

    我要演示的是采用AOP技术的框架原型实现:

    首先我们应该安装PostSharp(一定要安装要不能没办法注入处理代码)

    然后我们实现Orders对象

    using System;

    namespace PostSharp.Demo
    {
        
    public class Orders
        {
            [Permission]
            [Exception]
            
    public bool Add(string id, string orderName)
            {
                Console.WriteLine(
    "正在执行新增订单方法的操作,回车继续……");
                Console.ReadLine();
                Console.WriteLine(
    "您添加订单成功:编号:{0},名称:{1}", id, orderName);
                
    return true;
            }

            [Logger]
            [Permission]
            [Exception]
            
    public bool Delete(string id)
            {
                Console.WriteLine(
    "您删除订单成功:编号:{0}", id);

                
    return true;
            }
        }

    当然还要模拟一个用户资格认证


    namespace PostSharp.Demo
    {
        
    /// <summary>
        
    /// 静态的用户对象,用于存放当前登录用户,成员资格
        
    /// </summary>
        public static class User
        {
            
    private static string _userId;

            
    public static string UserId
            {
                
    get { return _userId; }
                
    set { _userId = value; }
            }

            
    public static bool AddEnable
            {
                
    get
                {
                    
    return (_userId.ToLower() == "admin");
                }
            }

            
    public static bool DeleteEnable
            {
                
    get
                {
                    
    return (_userId.ToLower() == "admin");
                }
            }
        }


    再然后我们实现权限控制方面PermissionAttribute,日志方面LoggerAttribute,异常处理方面ExceptionAttribute……

    PermissionAttribute

    using System;
    using PostSharp.Laos;

    namespace PostSharp.Demo
    {
        [Serializable]
        [global::System.AttributeUsage(AttributeTargets.All, Inherited 
    = true, AllowMultiple = false)]
        
    public class PermissionAttribute : OnMethodBoundaryAspect
        {
            
    public override void OnEntry(MethodExecutionEventArgs eventArgs)
            {
                
    if (!User.AddEnable)
                {
                    Console.WriteLine(
    "用户:【{0}】没有权限:【{1}】", User.UserId, eventArgs.Method);
                    eventArgs.FlowBehavior 
    = FlowBehavior.Return;
                }

            }
        }


    LoggerAttribute
    using System;
    using PostSharp.Laos;

    namespace PostSharp.Demo
    {
        [Serializable]
        [global::System.AttributeUsage(AttributeTargets.All, Inherited 
    = true, AllowMultiple = false)]
        
    public sealed class LoggerAttribute : OnMethodInvocationAspect
        {
            
    public override void OnInvocation(MethodInvocationEventArgs eventArgs)
            {
                DateTime time 
    = DateTime.Now;
                
    string log = "时间:{0},操作人员:{1},操作:{2}!";

                
    object[] arg = eventArgs.GetArguments();

                log 
    = String.Format(log, time, User.UserId, "删除Id为" + arg[0].ToString() + "的订单!");

                System.IO.File.WriteAllText(
    "C:\Log.Txt", log);
            }
        }


    ExceptionAttribute
    using System;
    using PostSharp.Laos;

    namespace PostSharp.Demo
    {
        [Serializable]
        [global::System.AttributeUsage(AttributeTargets.All, Inherited 
    = true, AllowMultiple = false)]
        
    public class ExceptionAttribute : OnExceptionAspect
        {
            
    public override void OnException(MethodExecutionEventArgs eventArgs)
            {
                Console.WriteLine(
    "程序出现异常:{0}", eventArgs.Exception.Message);
                eventArgs.FlowBehavior 
    = FlowBehavior.Return;
            }
        }


    然后再用控制台程序测试下能不能成功
    Orders order = new Orders();
                Console.WriteLine(
    "请输入用户名:");
                User.UserId 
    = Console.ReadLine();
                Console.WriteLine(
    "请输入密码:");
                Console.ReadLine();
                
    string id;

                LRedo:
                Console.WriteLine(
    "请输入您要执行的操作:新增(A),删除(D),退出(X)");

                
    string opt = Console.ReadLine();

                
    if (opt.ToLower() == "a")
                {
                    Console.WriteLine(
    "请输入订单编号:");
                    id 
    = Console.ReadLine();

                    Console.WriteLine(
    "请输入订单名称:");
                    
    string name = Console.ReadLine();
                    order.Add(id, name);
                }
                
    else if (opt.ToLower() == "d")
                {
                    Console.WriteLine(
    "请输入订单编号:");
                    id 
    = Console.ReadLine();
                    order.Delete(id);
                }
                
    else if (opt.ToLower() == "x")
                {
                }
                
    else
                {
                    Console.WriteLine(
    "您的输入不正确,请重新输入!");
                    
    goto LRedo;
                }

                Console.WriteLine(
    "按任意键退出……");
                Console.ReadLine(); 

    写完这些我们再反编译一下生成的exe文件,发现里面的Orders成了这模样了,神奇了?
    反编译后的代码

    代码很简单,我是采用控制台应用实现的,如果您有兴趣,请下载Demo源码玩玩。

     
     

    .net postsharp编译时生成的代码?

    最近下载了postsharp,发现给方法添加[HandleException] attribute后,反编译后自动生成了很多代码,思考了很久,还是不知道在编译该程序集时,怎么生成的,所以希望大家能给与指点。

    原类

    public class MyClass {

        public MyClass()     {     }

        [HandleException]    

    public int MyMethod(int x, string someString, float anotherFloat, bool theBool)    

        {

              int b = 0;

               int a = 5 / b;         return x + 1;    

         }

    }

    编译后,用ILSPY反编译后生成如下代码:

    望 各位大神能给与指点,谢谢。

     
     
     
  • 相关阅读:
    springboot整合mybatis实现增删改查小案例
    浅谈Nginx负载均衡原理与实现
    使用Cordova框架把Webapp封装成Hybrid App实践——Android篇
    ActiveMQ结合WebScoket应用例子以及介绍
    个人简介
    C#中的属性,字段,变量
    Aspose.Words 直接写response导出docx文档显示文件已损坏需要修复的解决办法
    System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(string, string)已过时的解决办法
    Aspose.Words:如何添加另一个WORD文档中的Node对象
    基于CPS变换的尾递归转换算法
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3273470.html
Copyright © 2011-2022 走看看