有时候我们需要在代码中对方法调用进行拦截,并修改参数和返回值,这种操作叫做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. JavaSE(十)之Map总结

    上一篇是总结了Collection接口的各种实现类,这一篇我将分享的是Map的总结,希望大家点评! 一.Map接口 1.1.为什么Collection不能满足集合的所有功能? Collection接口 ...

  2. linux fork两次避免僵尸进程的程序(简单)

    #include<stdio.h> #include<unistd.h> int main() { pid_t pid,pid1; int status; ) { printf ...

  3. JDBC操作数据库之批处理

    JDBC开发中,操作数据库需要和数据库建立连接,然后将要执行的SQL语句发送到数据库服务器,最后关闭数据库连接,都是按照这样的操做的,如果按照此流程要执行多条SQL语句,那么就要建立多个数据库连接,将 ...

  4. SQL性能优化十条经验(转)

    1.查询的模糊匹配 尽量避免在一个复杂查询里面使用 LIKE '%parm1%'-- 红色标识位置的百分号会导致相关列的索引无法使用,最好不要用. 解决办法: 其实只需要对该脚本略做改进,查询速度便会 ...

  5. 关于IOS的屏幕适配(iPhone)——Auto Layout和Size Classes

    Auto Layout和Size Classes搭配使用极大的方便了开发者,具体如何使用Auto Layout和Size Classes大家可以参考其他文章或者书籍,这里只提一点,在我们设置Size ...

  6. java文档操作

    背景:因是动态报表,1)作成excel模版2)数据填充3)转化为PDF提出解决方法:[open source]1)Apache Poi+I text2) JodConvert+OpenOffice/l ...

  7. EXIT_SUCCESS EXIT_FAILURE

    在vc++6.0下头文件stdlib.h中定义如下: /* Definition of the argument values for the exit() function */ #define E ...

  8. HDFS源码分析之NameNode(3)————RpcServer

    NameNodeRpcServer implements NamenodeProtocols NameNode支持核心即NameNodeRpcServer 实现ClientProtocol  支持客户 ...

  9. leetCode in Java (一)

    前言    感觉写博客是一个很耗心力的东西T_T,简单的写了似乎没什么用,复杂的三言两语也只能讲个大概,呸呸...怎么能有这些消极思想呢QAQ!那想来想去,先开一个leetcode的坑,虽然已经工作了 ...

  10. web应用中的异常处理

    楼主前几天写了一篇“Java子线程中的异常处理(通用)”文章,介绍了在多线程环境下3种通用的异常处理方法. 但是平时大家的工作一般是基于开发框架进行的(比如Spring MVC,或Spring Boo ...