Aop“面向切面编程”,与OOP“面向对象编程”一样是一种编程思路。个人理解:在不改变原有逻辑的基础上,注入其他行为。

基础代码(仿MVC拦截器实现)

namespace HGL.Toolkit.Aop
{
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
public sealed class AopAttribute : ContextAttribute, IContributeObjectSink
{
public AopAttribute() : base("Aop") { } //实现IContributeObjectSink接口当中的消息接收器接口
public IMessageSink GetObjectSink(MarshalByRefObject obj, IMessageSink next)
{
return new AopProxy(next);
}
} [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class AopMethodAttribute : Attribute
{
/// <summary>
/// 方法执行之前,执行代码
/// </summary>
public virtual bool OnMethodExecuting(System.Web.HttpContext context)
{
return true;
} /// <summary>
/// 方法执行之后,执行代码
/// </summary>
public virtual bool OnMethodExecuted(System.Web.HttpContext context)
{
return true;
}
}
} namespace HGL.Toolkit.Aop
{
public sealed class AopProxy : IMessageSink
{
//下一个接收器
private IMessageSink nextSink; public IMessageSink NextSink
{
get { return nextSink; }
} public AopProxy(IMessageSink nextSink)
{
this.nextSink = nextSink;
} //同步处理方法
public IMessage SyncProcessMessage(IMessage msg)
{
IMessage retMsg = null; //方法调用消息接口
IMethodCallMessage call = msg as IMethodCallMessage; var attributes = Attribute.GetCustomAttributes(call.MethodBase, typeof(AopMethodAttribute)); //如果被调用的方法没打AopMethodAttribute标签
if (call == null || attributes.Count() == 0)
{
retMsg = nextSink.SyncProcessMessage(msg);
}
//如果打了AopMethodAttribute标签
else
{
foreach (var attribute in attributes)
{
var obj = attribute.GetType(); var executing = obj.GetMethod("OnMethodExecuting");
if (executing != null)
{
var context=System.Web.HttpContext.Current;
executing.Invoke(attribute, new object[] { context });
}
} retMsg = nextSink.SyncProcessMessage(msg); foreach (var attribute in attributes)
{
var obj = attribute.GetType(); var executed = obj.GetMethod("OnMethodExecuted");
if (executed != null)
{
var context = System.Web.HttpContext.Current;
executed.Invoke(attribute, new object[] { context });
}
}
} return retMsg;
} //异步处理方法(不需要)
public IMessageCtrl AsyncProcessMessage(IMessage msg, IMessageSink replySink)
{
return null;
}
}
}

使用注意:

1.使用到Aop的类必须继承ContextBoundObject
2.使用到Aop的方法存在的类必须添加[Aop]特性
3.哪个方法需要实现Aop,就给那个方法添加[AopMethod]特性 AopMethod未实现任何业务逻辑,使用者需要重写该attribute /// <summary>
/// 方法执行之前,执行代码
/// </summary>
public virtual bool OnMethodExecuting()
{
return true;
} /// <summary>
/// 方法执行之后,执行代码
/// </summary>
public virtual bool OnMethodExecuted()
{
return true;
}

待续......(将执行前和执行后的方法使用代理委托机制,实现二次开发)

利用Attribute实现Aop的更多相关文章

  1. C# Unity依赖注入利用Attribute实现AOP功能

    使用场景? 很多时候, 我们定义一个功能, 当我们要对这个功能进行扩展的时候, 按照常规的思路, 我们一般都是利用OOP的思想, 在原有的功能上进行扩展. 那么有没有一种东西, 可以实现当我们需要扩展 ...

  2. C#.NET利用ContextBoundObject和Attribute实现AOP技术--AOP事务实现例子

    我前两天看见同事用写了用AOP技术实现缓存的方案,于是好奇看了一下这是怎么实现的.原来是用了.NET中的一个类ContextBoundObject和Attribute相关技术.其实个类在.NET Fr ...

  3. 利用C#实现AOP常见的几种方法详解

    利用C#实现AOP常见的几种方法详解 AOP面向切面编程(Aspect Oriented Programming) 是通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术. 下面这篇文章主要 ...

  4. .Net core 2.0 利用Attribute获取MVC Action来生成菜单

    最近在学习.net core的同时将老师的MVC5项目中的模块搬过来用,其中有一块就是利用Attribute来生成菜单. 一·首先定义Action实体 /// <summary> /// ...

  5. C#利用Attribute实现简易AOP介绍

    首先看一段简单的代码: public partial class Form1 : Form { public Form1() { InitializeComponent(); } //来自UI层的调用 ...

  6. C#当中利用Attribute实现简易AOP

    首先看一段简单的代码: public partial class Form1 : Form { public Form1() { InitializeComponent(); } //来自UI层的调用 ...

  7. C#利用Attribute实现简易AOP介绍 (转载)

    地址:http://dotnet.9sssd.com/csbase/art/638 http://wayfarer.blog.51cto.com/1300239/279913 http://devel ...

  8. ssm+redis 如何更简洁的利用自定义注解+AOP实现redis缓存

    基于 ssm + maven + redis 使用自定义注解 利用aop基于AspectJ方式 实现redis缓存 如何能更简洁的利用aop实现redis缓存,话不多说,上demo 需求: 数据查询时 ...

  9. 从Unity中的Attribute到AOP(七)

    本章我们将依然讲解Unity中的Attribute,继续命名空间在UnityEngine里的. PropertyAttribute,这个特性主要来控制变量或者类在Inspector里面的显示方式.和P ...

随机推荐

  1. C语言之基本算法39—字符串经典操作

    //字符串概念! /* ================================================================== 题目:练习字符串的 1.输入输出      ...

  2. [转]C语言预处理命令详解

    转载:https://www.cnblogs.com/clover-toeic/p/3851102.html 一  前言 预处理(或称预编译)是指在进行编译的第一遍扫描(词法扫描和语法分析)之前所作的 ...

  3. vue中的插槽slot理解

    本篇文章参考赛冷思的个人博客 1.函数默认传参 在我们写js函数我们的可能会给他们一个默认的参数,写法是 function show(age,name){ var age = age || 20; v ...

  4. WinForm无边框窗体移动方法

    C#WinForm无边框窗体移动方法.模仿鼠标单击标题栏移动窗体位置 这里介绍俩种办法 方法一:直接通过修改窗体位置从而达到移动窗体的效果 方法二:直接伪装发送单击任务栏消息,让应用程序误以为单击任务 ...

  5. Python day2 知识回顾

    标准库一般放在lib,site-packages放自己下载的:起的py文件名称不要和模块名字相同:import sys#print(sys.path)#打印去哪里寻找这些模块的路径#print(sys ...

  6. 通过Gradle来下载依赖的jar包

    前段时间在看Gradle文章方向其比ANT.Maven真的要简单很多,特别是在下载jar依赖方面下面就是用gradle写的一个jar包依赖下载的小例子: (1)建立build.gradle文件 (2) ...

  7. Sublime10个经常使用插件

    10. Package control Package control是必装插件,全部其它的插件和主题都能够通过它来安装. 希望它能出如今正式版默认包中. 首先參照以下的教程来安装Package Co ...

  8. 【Android Studio探索之路系列】之六:Android Studio加入依赖

    作者:郭孝星 微博:郭孝星的新浪微博 邮箱:allenwells@163.com 博客:http://blog.csdn.net/allenwells github:https://github.co ...

  9. css笔记(二)——几种经常使用的模式

    文本垂直居中 对于行内元素,height会自己主动收缩到包裹住文本的高度,所以不存在这个问题. 可是对于block和inline-block等盒子元素.假设设置了height属性,则文本默认会在上方显 ...

  10. menu-代码添加以及add方法参数意义

    今天需要给一个menu动态添加一个item,先把方法记录如下 @Override public boolean onCreateOptionsMenu(Menu menu) { menu.add(Me ...