第一个Postsharp插件

2023-05-16

代码

建立一个解决方案,里面添加2个类库项目FirstPSPlugin和FirstPlugin.Task。
一般一个Postsharp由两个部分构成,FirstPSPlugin这个程序集中定义一系列Custom Attributes,用于标记将要被

处理的语言元素。例如可以标记一个OnExceptionAttribute到一个方法中,只是这个方法将会在post-process阶段

被处理。总之这一部分中定义的类型完全是用来做标记的。我们使用插件的时候将会使用这些类标记我们代码的特

定位置。
第二部分是用来处理这些标记的,实现代码编织。安装完Postsharp后,Postsharp会自动和msbuild关联起来。当使

用msbuild编译程序集的时候,postsharp会检查正在编译的程序集的引用。如果引用了Postsharp.public这个程序

集,就会在常规编译结束后调用Postsharp对生成的程序集作进一步转换,例如修改方法中的il。

这两个项目都需要引用Postsharp.Public和Postsharp.Core。

先来看看FirstPSPlugin的实现。很简单,我们只需要1个类即可:
using System;

using PostSharp.Extensibility;

namespace MyPostSharp
{
    [Serializable]
    [AttributeUsage(AttributeTargets.Method)]
    public class MyMethodAttribute : Attribute, IRequirePostSharp
    {
        public PostSharpRequirements GetPostSharpRequirements()
        {
            var requirements = new PostSharpRequirements();
            requirements.PlugIns.Add("FirstPlugin.Task");
            requirements.Tasks.Add("FirstPlugin.Task.MyMethod");
            requirements.VariesWithInstance = false;
            return requirements;
        }
    }
}
注意FirstPSPlugin必须要强命名,否则Postsharp会报错误。
IRequirePostSharp接口只有一个方法,这个方法要求返回一个PostSharpRequirements类型的参数。在返回的实例

当中指明了处理这个Attribute所需要的Postsharp插件和Postsharp插件中具体用来处理这个Attribute的任务。
好,FirstPSPlugin已经完成了,可以Build之。

FirstPlugin.Task这个项目中只需要1个类即可,这个类实现了IL编织的具体过程:
namespace FirstPlugin.Task
{
    public class FirstPSTask : PostSharp.Extensibility.Task
    {
        public override bool Execute()
        {
            return base.Execute();
        }
    }
}
好,这个类我们先这样放着。

前面提到了2个概念,插件和任务。这里我们说的插件就是指FirstPlugin.Task这个程序集。那么什么是任务?
任务就是Build过程中必须执行的一项操作,通过一个xml文件定义。在FirstPlugin.Task中添加一个xml文

件,用psplugin做扩展名,输入以下内容:
<?xml version="1.0" encoding="utf-8" ?>
<PlugIn xmlns="http://schemas.postsharp.org/1.0/configuration">
  <TaskType Name="FirstPlugin.Task.MyMethod" Implementation="FirstPlugin.Task.FirstPSTask,

FirstPlugin.Task" Phase="Transform">
  </TaskType>
</PlugIn>
这个xml文件在FirstPlugin.Task这个插件中定义了一项任务,这个任务的名称“FirstPlugin.Task.MyMethod”就是

在前面那个自定义特性中所指定的任务名。这样任务就和自定义特性关联起来了。
在项目属性中把FirstPlugin.Task的输出路径改为“C:\Program Files\PostSharp 1.0\PlugIns\”,也Build之。这个

路径是PostSharp插件的公共路径,Postsharp在需要查找插件的时候会找这个路径。
必须把这个文件的属性“copy to output dir”设置为always。

虽然这个时候这个插件什么也不做,但是我们可以先在FirstPlugin.Task.FirstPSTask这个类的Execute方法上加一

个断点以观察其执行时机。
新建一个控制台解决方案FirstPSPlugin.Test。为了后面调试方便最好是新开一个vs建解决方案而不要把这个测试

项目添加到插件的那个解决方案中。
添加对PostSharp.Public和FirstPSPlugin的引用。
也只需要一个类:
using System;

namespace FirstPSPlugin.Test
{
    class Program
    {
        static void Main(string[] args)
        {
            Test();
        }

        [FirstPSPlugin.MyMethod]
        static void Test()
        {
            Console.WriteLine("void Program::Test()");
        }
    }
}
Build之。
好,现在没有任何激动人心的事发生。我们打开vs命令行,切换到FirstPSPlugin.Test项目目录下。
输入:msbuild FirstPSPlugin.Test.csproj /T:Rebuild /P:PostSharpAttachDebugger=True
好,出现了一个未处理异常。用打开FirstPlugin.Task的那个vs去调试这个异常。然后按F5就进入了我们在Execute

方法上的断点。这说明在Build FirstPSPlugin.Test的过程中调用了这个方法。

后面要做的事就是完成Execute方法,使用Postsharp提供的Code Model修改IL。这一部分我还没研究明白。
为了直观起见,写一个小例子:
using System;
using PostSharp.CodeModel;

namespace FirstPlugin.Task
{
    public class FirstPSTask : PostSharp.Extensibility.Task
    {
        public override bool Execute()
        {
            ModuleDeclaration md = this.Project.Module;
            foreach (var t in md.Types)
            {
                foreach (var m in t.Methods)
                {
                    foreach (var a in m.CustomAttributes)
                    {
                        if (a.Constructor.DeclaringType.ToString() ==

"[FirstPSPlugin]FirstPSPlugin.MyMethodAttribute")
                        {
                            using (InstructionWriter iw = new InstructionWriter())
                            {
                                InstructionSequence ins = m.MethodBody.CreateInstructionSequence();
                                m.MethodBody.RootInstructionBlock.AddInstructionSequence(ins,

PostSharp.Collections.NodePosition.Before, null);
                                iw.AttachInstructionSequence(ins);

                                iw.EmitInstruction(OpCodeNumber.Nop);
                                iw.EmitInstruction(OpCodeNumber.Nop);
                                iw.EmitInstruction(OpCodeNumber.Nop);
                                iw.EmitInstruction(OpCodeNumber.Nop);
                                iw.EmitInstruction(OpCodeNumber.Nop);

                                var mscorlib = this.Project.Module.FindMscorlib() as

AssemblyRefDeclaration;
                                var console = mscorlib.FindType("System.Console",

BindingOptions.Default) as TypeRefDeclaration;
                                foreach (var mr in console.MethodRefs.GetByName("WriteLine"))
                                {   //find Console.WriteLine(string) method ref
                                    if (mr.Signature.ParameterTypes.Count == 1 &&

mr.Signature.ParameterTypes[0].ToString() == "string")
                                    {
                                        iw.EmitInstructionString(OpCodeNumber.Ldstr, "Hello

Postsharp!");
                                        iw.EmitInstructionMethod(OpCodeNumber.Call, mr);
                                        break;
                                    }
                                }

                                m.CustomAttributes.Remove(a);
    
                                iw.DetachInstructionSequence(true);
                                break;

 

                            }
                        }
                    }

                }

            }
            return base.Execute();
        }
    }
}
现在FirstPSTask的Execute方法有了新的实现。好,重新编译测试项目,然后用ILDASM查看Program.Test方法:

.method private hidebysig static void Test() cil managed
{
    .maxstack 8
    L_0000: nop
    L_0001: nop
    L_0002: nop
    L_0003: nop
    L_0004: nop
    L_0005: ldstr "Hello Postsharp!"
    L_000a: call void [mscorlib]System.Console::WriteLine(string)
    L_000f: nop
    L_0010: ldstr "void Program::Test()"
    L_0015: call void [mscorlib]System.Console::WriteLine(string)
    L_001a: nop
    L_001b: ret
}

 
可以看到我们的的IL指令成功地注入了。Good, goooooood。

 

 

转载于:https://www.cnblogs.com/zhy2002/archive/2008/11/11/1331377.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

第一个Postsharp插件 的相关文章

  • 网络通信原理和过程

    当时查http协议的时候了解的一些网络底层的知识 xff0c 感觉挺有意思的 xff0c 就把多位博主的资料整料梳理出来整理到一堆 xff0c 就当是一篇科普文吧 一 网络的五层模型 如何分层有不同的模型 xff0c 有的模型分七层 xff
  • Springboot读取本地图片并显示

    在application xml中配置url访问路径和本地图片路径 xff1a 配置 url中访问路径 xff0c 这里为 xff1a localhost 8080 image 配置 本地图片保存的路径 xff0c image会根据D up
  • vue路由跳转到指定页面

    1 this router push name 39 Home 39 2 this router push path 39 view 39 3 this router replace name 39 Home 39 4 this route
  • Post方式提交,通过上下文HttpContext,Request[""]获取

    问题场景如下 xff1a 在项目的一般处理程序中 xff0c 所有方法都是通过 context Request 34 参数名 34 ToString 来获取参数的值 如果我直接将参数追加到URL后面 xff0c 直接Post xff0c 后
  • maven项目添加mysql的链接驱动

    Maven项目中添加JDBC驱动 在pom xml配置文件中添加 lt dependency gt lt groupId gt mysql lt groupId gt lt artifactId gt mysql connector jav
  • 2.5年, 从0到阿里

    从来没有想到自己的求职之路会这么顺利 第一次投阿里就拿到了offer 以前一直都是做好被刷的准备的 3月31号晚上收到了来自阿里的正式offer 签下录取意向书 粗略算了一下 从2012年9月份正式入学进入计算机系到2015年3月签下阿里o
  • 我的2013—弃金融IT,从SAP业务

    我的2013 xff0c 是动荡的一年 xff1b 这一年 xff0c 我跳巢了 xff1b 这一年 xff0c 我换行业了 xff1b 这一年 xff0c 我离开了生活5年的长春 xff0c 来到成都 xff1b 这一年 xff0c 我放
  • [转载]LazyWriter(惰性写入器) 进程的作用

    Q What Does the LazyWriter Process Do The LazyWriter process is a periodic process that checks the status of BPool buffe
  • Python——爬取百度百科关键词1000个相关网页

    Python简单爬虫 爬取百度百科关键词1000个相关网页 标题和简介 网站爬虫由浅入深 xff1a 慢慢来 分析 xff1a 链接的URL分析 xff1a 数据格式 xff1a 爬虫基本架构模型 xff1a 本爬虫架构 xff1a 源代码
  • python2:TypeError: must be string without null bytes, not str

    Stack Overflow QuestionsDeveloper JobsTagsUsers Log In Sign Up Join Stack Overflow to learn share knowledge and build yo
  • 读书笔记之二—大泥球和顶级的设计

    大泥球 世界上最常用的软件体系结构 xff0c 一个经久不衰的传奇 大泥球是一件很神奇的事情 xff0c 阅读文章里列举了大泥球出现的一系列原因 xff0c 但是我们貌似很少在其他的领域看到这么不专业的专业行为 xff0c 从这个角度看看
  • 类的命名规则

    类定义的命名规则 xff0c 是命名空间 xff08 应用程序名称 xff09 指向应用程序的app文件夹 xff0c 而类名除了命名空间和类名中最后部分之外 xff0c 其他的都是文件夹的名称 类名的最后部分加上 js就是类的文件名 xf
  • 远程桌面 Rdp文件的生成

    最近由于项目需要 xff0c 需要做一个rdp文件上成 xff0c 然后可以直接连远程桌面的功能 xff0c 在度娘和谷叔搜索一番 xff0c 所得甚少 闲话少说 xff0c 来点干货 xff1a 看看系统给提供的是啥样的 我们要关心得是
  • 防恶意解析,禁止用IP访问网站的Apache设置 修改 httpd.conf 实现

    一般来说 xff0c 网站可以用域名和IP来访问 你的网站可以通过IP直接访问 xff0c 本来这没什么问题 xff0c 但是会有些隐患 xff1a 由于搜索引擎也会收录你的IP地址的页面 xff0c 所以同一个页面搜索引擎会重复收录 xf
  • linux怎么改程序图标,如何在Ubuntu Unity上修改应用程序图标

    这篇文章将教大家在Ubuntu Unity上修改应用程序图标 xff0c 这个教程适合于Ubuntu 14 04 Ubuntu 13 10 Ubuntu 12 04 等使用Unity作为默认桌面环境的发行版 在Unity桌面环境 xff0c
  • 服务器显示不明用户远程过,服务器显示不明用户远程过

    服务器显示不明用户远程过 内容精选 换一换 Windows操作系统云服务器蓝屏 xff0c 如图1所示 使用了来源不明的第三方软件 CPU占用过高导致 因为误操作或者病毒引起的系统文件 注册表损坏 操作系统在蓝屏的情况下 xff0c 会显示
  • nginx反向代理局域网访问外网

    配置内网hosts vim etc hosts 添加 host1 能连外网的服务器ip central maven org 2 在host1 服务器上nginx配置 server listen 80 server name central
  • KVM详解

    一 KVM的简介 1 KVM简介 KVM xff0c 基于内核的虚拟机 xff08 kernel based virtual machine xff09 xff0c 是一种用于Linux内核中的虚拟化基础设施 xff0c 可以将Linux内
  • Windows 10 L2TP/IPSec 防火墙配置

    This guide will walk you through how to open your Windows 10 firewall to allow the L2TP IPSec protocol For more about th
  • 智能革命之读书笔记

    我在孩童时代听说机器人时内心觉得那是距离我所生活的时代遥不可及的事物 xff0c 大学时听说人工智能 xff0c 一直对它敬而远之 xff0c 甚至对它有一种畏惧情绪 xff0c 心里一直有种担忧 xff0c 人工智能高度发展 xff0c

随机推荐

  • MySQL、MariaDB修改默认字符集

    修改2017 4 9 xff1a 最近在使用MariaDB xff0c 遇到了同样的问题 xff1a 中文乱码 因为mariadb他有好几个ini文件 xff0c 但是可以根据自己开发需要创建一个my ini 然后我试着去修改mariadb
  • Visual Studio 2019 Serial Keys

    Visual Studio span class hljs number 2019 span Enterprise BF8Y8 GN2QH T84XB QVY3B RC4DF Visual Studio span class hljs nu
  • Android 修改底部导航栏navigationbar的颜色

    Android 修改底部导航栏navigationbar的颜色 getWindow setNavigationBarColor Color BLUE 写法一 getWindow setNavigationBarColor getResour
  • 解决 ubuntu 开机后键盘鼠标失灵!

    近期不知安装了什么package xff0c 导致 ubuntu 开机后键盘鼠标一直没法用 xff0c 刚开始以为是 ubuntu 桌面环境崩溃了 xff0c 后来发现系统能显示连接到网络 时间也在运行 xff0c 那应该就是键盘鼠标失灵了
  • Mac OS 使用SSH/VNC远程控制树莓派(路由器媒介)

    因为自己第一次接触树莓派 xff0c 基础掌握的不好 xff0c 查阅网上的资料也都不是很全面 xff0c 因此这篇文章对网上的几种方法进行了综合整理 xff0c 适合小白探索 第一步 xff1a 硬件准备 树莓派3B xff0b 电源线
  • 多个生产者与消费者

    生产者消费者问题属于有界缓冲区问题 我们现在讲述多个生产者向一个缓冲区中存入数据 xff0c 多个生产者从缓冲区中取数据 共享缓冲区作为一个环绕缓冲区 xff0c 存数据到头时再从头开始 我们使用一个互斥量保护生产者向缓冲区中存入数据 由于
  • windows系统IO性能测试

    关键词 xff1a sql server io测试 下载链接 xff1a http www onlinedown net soft 57364 htm CrystalDiskMark 硬盘检测工具 xff0c 一个测试你的硬盘或者存储设备的
  • jnhs解决办法部署错误: 未能启动 Tomcat, 服务器端口 8080 已在使用中。

    tomcat死掉了 重启netbeans报错 当然重启电脑是不可能重启电脑的 这辈子都不会重启电脑 解决方法 1 win 43 R 输入cmd回车进打开命令行工具 2 输入 netstat ano findstr 8080 查看占用8080
  • Linux文件处理命令

    命令格式 命令 选项 参数 例如 xff1a ls la etc 说明 xff1a 个别命令不遵守此格式 当有多个选项时 xff0c 可以写在一起 简化选项与完整选项 xff08 a 等于 all xff09 目录处理命令 命令名称 xff
  • win7无线网络连接

    今儿个真高兴啊 xff0c 我的无线网络又能自动连接上了 xff0c 困扰了很久的问题终于解决了 有很长一段时间 xff0c 开机后网络连接的标志总是打了个叉叉 xff08 前提是没有插网线 xff09 xff0c 也就是说 xff0c 不
  • 最新百度 阿里 华为 腾讯 谷歌面试笔试题及解析 (转)

    原文地址 xff1a http m blog csdn net blog panfengyun12345 12618453 8月15日 xff0c 百度2道面试题 xff1a 1 来自 编程之美 的概率题 xff1a 一个桶里面有白球 黑球
  • 归并排序——C语言

    归并排序 归并排序 xff08 MERGE SORT xff09 是建立在归并操作上的一种有效的排序算法 该算法采用经典的分治 xff08 divide and conquer xff09 策略 xff08 分治法将问题分 divide 成
  • Operating system error number 5 in a file operation. 问题解决方案

    mysql 5 7数据库体积达到32G xff0c 磁盘空间不足 xff0c 需要迁移 xff0c 迁移后出现 xff1a 2018 09 05T03 17 41 016760Z 0 ERROR InnoDB The error means
  • [转]Ubuntu默认使用root用户登录并免去输入密码

    启用Root用户登录 Ctrl 43 Alt 43 T进入终端 输入cd usr share lightm ightm conf d 如果提示你没有那个文件或目录 那就一次次的进入目录 进入之后会看到如图所示的几个文件 这里写图片描述 输入
  • manifest.json文件介绍

    必须 34 manifest version 34 2 清单文件的版本 xff0c 这个必须写 xff0c 而且必须是2 34 name 34 34 My Extension 34 34 version 34 34 versionStrin
  • Html Code 基本应用

    1 文本框焦点问题 onBlur 当失去输入焦点后产生该事件 onFocus 当输入获得焦点后 xff0c 产生该文件 Onchange 当文字值改变时 xff0c 产生该事件 Onselect 当文字加亮后 xff0c 产生该文件 lt
  • html5 layout,CSS Grid Layout 手记(教程指南)

    CSS Grid Layout 网格 栅格布局 是 CSS 最强大的布局系统 xff0c 随着设备和浏览器的升级 xff0c 将会是未来的主流的布局方案之一 一 介绍 Introduction 概述 Basic CSS Grid Layou
  • minimist的用法

    npm install minimist save 后 xff0c usr bin env node var parseArgs 61 require 39 minimist 39 process argv slice 2 console
  • android core apps华为,华为HMS Core 4.0全面上线 让开发者专注于应用创新发

    日前 xff0c 华为面向全球发布了HMS Core 4 0 HMS Core是华为终端云服务开放能力的合集 xff0c 汇聚了华为终端芯 端 云能力 xff0c 包含一整套开放的HMS Apps和HMS Core HMS Capabili
  • 第一个Postsharp插件

    代码 建立一个解决方案 里面添加2个类库项目FirstPSPlugin和FirstPlugin Task 一般一个Postsharp由两个部分构成 xff0c FirstPSPlugin这个程序集中定义一系列Custom Attribute