1、先定义一个 拦截属性 AopAttribute

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace ZH.Aop
{
using System.Runtime.Remoting.Contexts;
using System.Runtime.Remoting.Activation;
[AttributeUsage(AttributeTargets.Class)]
public class AopAttribute : Attribute, IContextAttribute
{
public void GetPropertiesForNewContext(IConstructionCallMessage msg)
{
msg.ContextProperties.Add(new AOPProperty());
}
public bool IsContextOK(Context ctx, IConstructionCallMessage msg)
{
AOPProperty aOPProperty = ctx.GetProperty("Aop") as AOPProperty;
return aOPProperty!=null;
}
}
}

2  实现  ContextProperty, IContributeServerContextSink

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace ZH.Aop
{
using System.Runtime.Remoting.Contexts;
using System.Runtime.Remoting.Messaging;
internal class AOPProperty : IContextProperty, IContributeServerContextSink
{
public string Name => "Aop"; public AOPProperty()
{
Console.WriteLine(nameof(AOPProperty));
}
public void Freeze(Context newContext)
{ }
public bool IsNewContextOK(Context newCtx)
{
var result = newCtx.GetProperty("Aop");
return result != null;
} public IMessageSink GetServerContextSink(IMessageSink nextSink)
{
Aspect aspect = new Aspect(nextSink);
return aspect;
}
}
}

3、  实现事件 执行类(主要) Aspect

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
namespace ZH.Aop
{
using System.Runtime.Remoting.Messaging;
using System.Dynamic;
using ZH.Aop.AopListener;
using ZH.Aop.ArgsModel;
internal class Aspect : IMessageSink
{
private IMessageSink nextSink = null;
public Aspect(IMessageSink messageSink)
{
nextSink = messageSink;
}
public IMessageSink NextSink => nextSink; public IMessageCtrl AsyncProcessMessage(IMessage msg, IMessageSink replySink)
{
return null;
}
/// <summary>
/// 处理事件
/// </summary>
/// <param name="msg"></param>
/// <returns></returns>
public IMessage SyncProcessMessage(IMessage msg)
{ // 方法执行之前】
dynamic defaultValue = new ExpandoObject();
var callMsg = msg as IMethodCallMessage;
AopEventArgs aopEventArgs = new AopEventArgs();
aopEventArgs.StartTime = DateTime.Now;
aopEventArgs.MethodName = callMsg.MethodName;
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
MethodListen.GetInstance().BeginMethod(aopEventArgs); // 如果不是构造函数
if (!callMsg.MethodBase.IsConstructor)
{
defaultValue = ((System.Reflection.MethodInfo)(callMsg.MethodBase)).ReturnParameter.DefaultValue;
// 实例 如果方法的名称是 SetName 则放弃执行
// if (callMsg.MethodName == "SetName")
// return new ReturnMessage(defaultValue, callMsg.Args, callMsg.ArgCount, callMsg.LogicalCallContext, callMsg);
}
try
{
IMessage returnMsg = nextSink.SyncProcessMessage(msg);
stopwatch.Stop();
aopEventArgs.OperateTime = stopwatch.ElapsedMilliseconds;
aopEventArgs.EndTime = DateTime.Now;
return returnMsg;
}
catch (Exception ex)
{
aopEventArgs.Exception = ex;
throw;
}
finally
{
// 执行方法之后
MethodListen.GetInstance().AfterMethod(aopEventArgs);
}
} }
}

4  另外 监听事件的执行

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace ZH.Aop.AopListener
{
using ZH.Aop.ArgsModel;
public interface IMethodListen
{
event EventHandler<AopEventArgs> OnMethodBegin;
event EventHandler<AopEventArgs> OnMethodAfter;
}
}

实现上面接口:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace ZH.Aop.AopListener
{
using ZH.Aop.ArgsModel;
public class MethodListen : IMethodListen
{
public event EventHandler<AopEventArgs> OnMethodBegin;
public event EventHandler<AopEventArgs> OnMethodAfter;
private static MethodListen _methodListen = null;
public static MethodListen GetInstance()
{
if (_methodListen == null)
_methodListen = new MethodListen();
return _methodListen;
} internal void BeginMethod(AopEventArgs aopEventArgs)
{
if (OnMethodBegin != null)
{
OnMethodBegin(this, aopEventArgs);
}
}
internal void AfterMethod(AopEventArgs aopEventArgs)
{
if (OnMethodAfter != null)
{
OnMethodAfter(this, aopEventArgs);
}
}
}
}

6 参数 model

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace ZH.Aop.ArgsModel
{
using System.Reflection;
public class AopEventArgs : EventArgs
{
/// <summary>
/// 方法名称
/// </summary>
public string MethodName { get; set; } /// <summary>
/// 执行时间
/// </summary>
public long OperateTime { get; set; } /// <summary>
/// 异常信息
/// </summary>
public Exception Exception { get; set; }
/// <summary>
/// 开始时间
/// </summary>
public DateTime StartTime { get; set; }
/// <summary>
/// 结束时间
/// </summary>
public DateTime EndTime { get; set; }
}
}

测试:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ZH.Aop;
using ZH.Aop.AopListener;
using ZH.Aop.ArgsModel;
namespace Demo.Aop
{
class Program
{ static void Main(string[] args)
{
MethodListen methodListen = MethodListen.GetInstance();
methodListen.OnMethodBegin += new EventHandler<AopEventArgs>(OnMethodBegin);
methodListen.OnMethodAfter += new EventHandler<AopEventArgs>(OnMethodAfter);
TestAop testAop = new TestAop();
for (int i=;i<;i++)
{ var s = testAop.SetName("zheng", );
}
Console.ReadLine();
}
public static void OnMethodBegin(object sender, AopEventArgs e)
{
Console.WriteLine($"开始执行--方法名称{e.MethodName} 开始时间:{e.EndTime}");
}
public static void OnMethodAfter(object sender, AopEventArgs e)
{
Console.WriteLine($"执行后--方法名称{e.MethodName} 总共时间{e.OperateTime} 结束时间:{e.EndTime}");
}
} [Aop]
public class TestAop : ContextBoundObject
{ public string SetName(string name, int age)
{
return $"{name}{age}";
} } }

Attribute 实现Aop的更多相关文章

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

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

  2. 利用Attribute实现Aop

    Aop“面向切面编程”,与OOP“面向对象编程”一样是一种编程思路.个人理解:在不改变原有逻辑的基础上,注入其他行为. 基础代码(仿MVC拦截器实现) namespace HGL.Toolkit.Ao ...

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

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

  4. 从Unity中的Attribute到AOP(六)

    本文将重点对Unity剩下常用的Attribute进行讲解,其他不常用的Attribute各位可以自行去官方文档查阅. 首先是UnityEngine命名空间下的. ColorUsage,这个主要作用于 ...

  5. 从Unity中的Attribute到AOP(五)

    今天主要来讲一下Unity中带Menu的Attribute. 首先是AddComponentMenu.这是UnityEngine命名空间下的一个Attribute. 按照官方文档的说法,会在Compo ...

  6. 从Unity中的Attribute到AOP(四)

    本篇我们将逐一讲解Unity中经常使用的Attribute(Unity对应的文档版本为2018.1b). 首先是Serializable,SerializeField以及NonSerialized,H ...

  7. 从Unity中的Attribute到AOP(三)

    上一篇我们对系统的Attributes进行了MSIL代码的查看,了解到了其本质就是一个类的构造函数.本章我们将编写自己的Attributes. 首先我们定义书的属性代码,如下: [AttributeU ...

  8. 从Unity中的Attribute到AOP(二)

    上一篇文章我们初步了解了一下Attributes的含义,并且使用系统自带的Attributes写了点代码.在进一步解剖我们的代码之前,我觉得有个概念可能需要巩固一下:什么是元数据? 我们知道C#代码会 ...

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

    首先来看一下微软官方对Attributes(C#)的定义: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/conce ...

随机推荐

  1. 【纪中集训】2019.08.01【NOIP提高组】模拟 A 组TJ

    T1 Description 给定一个\(N*N(N≤8)\)的矩阵,每一格有一个0~5的颜色.每次可将左上角的格子所在连通块变为一种颜色,求最少操作数. Solution IDA*=启发式迭代加深 ...

  2. MailUtils

    /** *包名:com.thinkgem.jeesite.test *描述:package com.thinkgem.jeesite.test; */ package com.thinkgem.jee ...

  3. H5页面前后端通信 (3种方式简单介绍)

    1.ajax:短连接 2.websocket :长连接,双向的.   node搭建的websocket服务器,推送信息给客户端浏览器 :https://www.cnblogs.com/fps2tao/ ...

  4. python实现人民币大写转换

    问题描述: 银行在打印票据的时候,常常需要将阿拉伯数字表示的人民币金额转换为大写表示,现在请你来完成这样一个程序. 在中文大写方式中,0到10以及100.1000.10000被依次表示为: 零 壹 贰 ...

  5. gdb流程控制(例: 循环打印数组)

    参考:https://blog.csdn.net/justlinux2010/article/details/9453151 循环/条件 在gdb的脚本中循环遍历整个哈希表,并且加上判断条件来进行统计 ...

  6. CJE-Jenkins认证工程师备考指南1-考试简介

    CloudBees公司提供两项认证 Jenkins工程师(CJE)考试 包括60个选择题 测试开源Jenkins的知识. CloudBees 平台工程师(CCJE)考试 包含90个问题: 60个问题测 ...

  7. mysql常用内置函数-查询语句中不能使用strtotime()函数!

    来自:http://yushine.iteye.com/blog/775407 FROM_UNIXTIME把 unix时间戳转换为标准时间 unix_timestamp把标准时间转换为 unix时间戳 ...

  8. Linux环境下Eclipse对C++新特性的支持设置

    Linux环境下Eclipse对C++新特性的支持设置     今天写一个简单的关于C11中的array容器的测试程序如下, #include <iostream> #include &l ...

  9. 业务基类对象BaseBLL

    using System; using System.Collections; using System.Data; using System.Text; using System.Collectio ...

  10. python之正则表达式【re】

    在处理字符串时,经常会有查找符合某些规则的字符串的需求.正则表达式就是用于藐视这些规则的工具.换句话说,正则表达式是记录文本规则的代码. 1.行定位符. 行定位符就是用来表示字符串的边界,“^”表示开 ...