有时候我们需要在代码中对方法调用进行拦截,并修改参数和返回值,这种操作叫做AOP(面向切面编程)

不过需要注意的是,AOP的效率很慢,在需要高效率场合慎用.

以下是C#的AOP方法:

首先建立一个控制台工程

写一个calc类,里面有add个方法:

一会将拦截这个方法,对出参,入参进行检查.

public class Calc
{
public int add(int a, int b)
{
return a + b;
}
} class Program
{
static void Main(string[] args)
{
Console.Title = "";
Console.WriteLine(new Calc().add(1, 0));
Console.WriteLine(new Calc().add(2, 3));
Console.WriteLine(new Calc().add(1, 1));
Console.ReadKey(true);
}
}

运行效果:



非常普通

接着添加一个文件



里面的代码:

首先写一个消息接收器类,用来处理拦截到的调用:

/// <summary>
/// AOP方法处理类,实现了IMessageSink接口
/// </summary>
public sealed class MyAopHandler : IMessageSink
{
/// <summary>
/// 下一个接收器
/// </summary>
public IMessageSink NextSink { get; private set; }
public MyAopHandler(IMessageSink nextSink)
{
this.NextSink = nextSink;
} /// <summary>
/// 同步处理方法
/// </summary>
/// <param name="msg"></param>
/// <returns></returns>
public IMessage SyncProcessMessage(IMessage msg)
{
//方法调用消息接口
var call = msg as IMethodCallMessage; //只拦截指定方法,其它方法原样释放
if (call == null || (Attribute.GetCustomAttribute(call.MethodBase, typeof(AOPMethodAttribute))) == null || call.MethodName != "add") return NextSink.SyncProcessMessage(msg); //判断第2个参数,如果是0,则强行返回100,不调用方法了
if (((int)call.InArgs[1]) == 0) return new ReturnMessage(100, call.Args, call.ArgCount, call.LogicalCallContext, call); //判断第2个参数,如果是1,则参数强行改为50(失败了)
//if (((int)call.InArgs[1]) == 1) call = new MyCall(call, call.Args[0], 50);//方法1 失败了
//if (((int)call.InArgs[1]) == 1) call.MethodBase.Invoke(GetUnwrappedServer(), new object[] { call.Args[0], 50 });//方法2 (无法凑够参数) var retMsg = NextSink.SyncProcessMessage(call); //判断返回值,如果是5,则强行改为500
if (((int)(retMsg as IMethodReturnMessage).ReturnValue) == 5) return new ReturnMessage(500, call.Args, call.ArgCount, call.LogicalCallContext, call); return retMsg;
} /// <summary>
/// 异步处理方法(暂不处理)
/// </summary>
/// <param name="msg"></param>
/// <param name="replySink"></param>
/// <returns></returns>
public IMessageCtrl AsyncProcessMessage(IMessage msg, IMessageSink replySink) => null;
}

然后声明两个特性,用来指明我们要拦截的Methot,以及它所在的Class:

/// <summary>
/// 贴在方法上的标签
/// </summary>
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
public sealed class AOPMethodAttribute : Attribute { } /// <summary>
/// 贴在类上的标签
/// </summary>
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
public sealed class AOPAttribute : ContextAttribute, IContributeObjectSink
{
public AOPAttribute() : base("AOP") { } /// <summary>
/// 实现消息接收器接口
/// </summary>
/// <param name="obj"></param>
/// <param name="next"></param>
/// <returns></returns>
public IMessageSink GetObjectSink(MarshalByRefObject obj, IMessageSink next) => new MyAopHandler(next);
}

回到Calc类,给类和Methot加上特性标签:

[AOP]
public class Calc : ContextBoundObject
{
[AOPMethod]
public int add(int a, int b)
{
return a + b;
}
}

运行,效果如下:



可以看到返回值已经被拦截修改处理过了

试一下继承:

[AOP]
public class Calc : ContextBoundObject
{
[AOPMethod]
public virtual int add(int a, int b)
{
return a + b;
}
} public class Calc2 : Calc
{
public override int add(int a, int b)
{
return a + b;
}
} class Program
{
static void Main(string[] args)
{
Console.Title = "";
Console.WriteLine(new Calc2().add(1, 0));
Console.WriteLine(new Calc2().add(2, 3));
Console.WriteLine(new Calc2().add(1, 1));
Console.ReadKey(true);
}
}

运行效果:

至此AOP的介绍结束,不过有一点很遗憾,无法修改参数,找了一下午资料无结果,如果谁知道怎么操作能否回复告知一下?

C# AOP 面向切面编程之 调用拦截的更多相关文章

  1. AOP 面向切面编程, Attribute在项目中的应用

    一.AOP(面向切面编程)简介 在我们平时的开发中,我们一般都是面对对象编程,面向对象的特点是继承.多态和封装,我们的业务逻辑代码主要是写在这一个个的类中,但我们在实现业务的同时,难免也到多个重复的操 ...

  2. [转] AOP面向切面编程

    AOP面向切面编程 AOP(Aspect-Oriented Programming,面向切面的编程),它是可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术. ...

  3. 从壹开始前后端分离【 .NET Core2.0 +Vue2.0 】框架之十 || AOP面向切面编程浅解析:简单日志记录 + 服务切面缓存

    代码已上传Github+Gitee,文末有地址 上回<从壹开始前后端分离[ .NET Core2.0 Api + Vue 2.0 + AOP + 分布式]框架之九 || 依赖注入IoC学习 + ...

  4. Spring:AOP面向切面编程

    AOP主要实现的目的是针对业务处理过程中的切面进行提取,它所面对的是处理过程中的某个步骤或阶段,以获得逻辑过程中各部分之间低耦合性的隔离效果. AOP是软件开发思想阶段性的产物,我们比较熟悉面向过程O ...

  5. Spring Boot2(六):使用Spring Boot整合AOP面向切面编程

    一.前言 众所周知,spring最核心的两个功能是aop和ioc,即面向切面和控制反转.本文会讲一讲SpringBoot如何使用AOP实现面向切面的过程原理. 二.何为aop ​ aop全称Aspec ...

  6. Z从壹开始前后端分离【 .NET Core2.0/3.0 +Vue2.0 】框架之十 || AOP面向切面编程浅解析:简单日志记录 + 服务切面缓存

    本文梯子 本文3.0版本文章 代码已上传Github+Gitee,文末有地址 大神反馈: 零.今天完成的深红色部分 一.AOP 之 实现日志记录(服务层) 1.定义服务接口与实现类 2.在API层中添 ...

  7. AOP(面向切面编程)大概了解一下

    前言 上一篇在聊MemoryCache的时候,用到了Autofac提供的拦截器进行面向切面编程,很明显能体会到其优势,既然涉及到了,那就趁热打铁,一起来探探面向切面编程. 正文 1. 概述 在软件业, ...

  8. Javascript aop(面向切面编程)之around(环绕)

    Aop又叫面向切面编程,其中“通知”是切面的具体实现,分为before(前置通知).after(后置通知).around(环绕通知),用过spring的同学肯定对它非常熟悉,而在js中,AOP是一个被 ...

  9. Method Swizzling和AOP(面向切面编程)实践

    Method Swizzling和AOP(面向切面编程)实践 参考: http://www.cocoachina.com/ios/20150120/10959.html 上一篇介绍了 Objectiv ...

随机推荐

  1. Winfrom 简单的安卓手机屏幕获取和安卓简单操作

    为啥我要做这个东西了,是因为经常要用投影演示app ,现在有很多这样的软件可以把手机界面投到电脑上 ,但都要安装,比如说360的手机助手,我又讨厌安装,于是就自己捣鼓了下 做了这个东西, 实现了以下简 ...

  2. Linux文件管理_1

    在Linux中,全部都是文件,所以文件管理在Linux上格外重要,在我们学习文件管理前,我们先学习几个关于文件的命令,之后才能更好的学习文件管理. 目录 pwd命令 cd命令 列出文件内容ls 查看文 ...

  3. birt IE8 IE9 兼容问题

    我自己的应用,birt展示报表的时候,在firefox和IE下显示的样式: IE8下的: Firefox下的: 我的项目,应用birt部分的结构如下: 1, prototype.js ,查找下面这段代 ...

  4. hadoop2.x的变化

    HDFS Federation(HDFS联邦) HDFS有两个主要层: Namespace 由目录.文件和块组成:支持所有命名空间对文件和目录的操作. Block Storage Service 由B ...

  5. Excel 若某列包含某个字符则特定列显示特定字符

    今天在写Excel , 有很多重复的数据, 在想 如果 可以像Java  一样 筛选就好了 这样的效果 if ("adj".equals(sheet1.A1)){ sheet1.B ...

  6. [js高手之路] html5 canvas系列教程 - 认识canvas以及基本使用方法

    canvas是html5中引入的一个新元素,俗称画布,既然是画布,当然是用来画图的.canvas技术指的是利用javascript操作canvas元素绘制图形的技术,要使用canvas,一定要浏览器支 ...

  7. java 对象转型

    一.对象转型介绍 对象转型分为两种:一种叫向上转型(父类对象的引用或者叫基类对象的引用指向子类对象,这就是向上转型),另一种叫向下转型.转型的意思是:如把float类型转成int类型,把double类 ...

  8. UNREFERENCED_PARAMETER

    作用:告诉编译器,已经使用了该变量,不必检测警告! 在VC编译器下,如果您用最高级别进行编译,编译器就会很苛刻地指出您的非常细小的警告.当你生命了一个变量,而没有使用时,编译器就会报警告:" ...

  9. JSP入门 Filter

    Filter,它的名字是过滤器,可以批量拦截修改servlet的请求和响应. 需要实现接口Filter 配置 <filter> <filter-name>EncodingFil ...

  10. Redis 的安装与使用

    环境:CentOS 6.6 Redis 版本:redis-3.0 (考虑到 Redis3.0 在集群和性能提升方面的特性,rc 版为正式版的候选版,而且很快就出正式版) 安装目录:/usr/local ...