有时候我们需要在代码中对方法调用进行拦截,并修改参数和返回值,这种操作叫做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. JQUERY选中问题

    单选,复选,下拉列表的全选选中问题 基本思路就是找到元素,操作元素,关于怎么找看jquery简介,主要学习记住具体操作用到的方法   复选框的全选以及设置选中问题:   jquery中提供prop方法 ...

  2. python函数式编程,列表生成式

    1.python 中常见的集中存储数据的结构: 列表 集合 字典 元组 字符串 双队列 堆 其中最常见的就是列表,字典. 2.下面讲一些运用循环获取字典列表的元素 >>> dic={ ...

  3. java-枚举一些字典信息的例子

    一个典型的枚举应用的例子 package opstools.vtm.dictionary.enums; import opstools.framework.view.ResourceValue; /* ...

  4. Redis集群介绍

    http://mt.sohu.com/20160601/n452401108.shtml

  5. 02-windows 安装以太坊 ethereum 客户端 (win7-64)-大叔思维

    以太坊(Ethereum)是一个运行智能合约的去中心化平台(Platform for Smart Contract),平台上的应用按程序设定运行,不存在停机.审查.欺诈.第三方人为干预的可能.以太坊平 ...

  6. ubuntu中设置php7.0-fpm开机自启动

    1.编写/etc/init/php7.0-fpm脚本如下 sudo vim /etc/init/php7.0-fpm #!/bin/sh### BEGIN INIT INFO# Provides: p ...

  7. 用css绘制各种图形

    1.用css绘制三角形 http://www.cnblogs.com/blosaa/p/3823695.html

  8. Spring Boot Document Part II(上)

    Part II. Getting started 这一章内容适合刚接触Spring Boot或者"Spring"家族的初学者!随着安装指导说明,你会发现对Spring boot有一 ...

  9. 【小程序】微信小程序实现各种特效实例

    写在前面 最近在负责一个微信小程序的前端以及前后端接口的对接的项目,整体上所有页面的布局我都已经搭建完成,里面有一些常用的特效,总结一下,希望对大家和我都能有所帮助 实例1:滚动tab选项卡 先看一下 ...

  10. Hbase对时,时差范围的确定

    Hbase对时具有严格的要求,集群内部所有机器之间的时差默认不能超过30秒,也就是说,一旦某个regionserver节点上的时间与master节点上的时间差值超过30秒,就会导致相应的regions ...