Attribute 实现Aop
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的更多相关文章
- C#.NET利用ContextBoundObject和Attribute实现AOP技术--AOP事务实现例子
我前两天看见同事用写了用AOP技术实现缓存的方案,于是好奇看了一下这是怎么实现的.原来是用了.NET中的一个类ContextBoundObject和Attribute相关技术.其实个类在.NET Fr ...
- 利用Attribute实现Aop
Aop“面向切面编程”,与OOP“面向对象编程”一样是一种编程思路.个人理解:在不改变原有逻辑的基础上,注入其他行为. 基础代码(仿MVC拦截器实现) namespace HGL.Toolkit.Ao ...
- 从Unity中的Attribute到AOP(七)
本章我们将依然讲解Unity中的Attribute,继续命名空间在UnityEngine里的. PropertyAttribute,这个特性主要来控制变量或者类在Inspector里面的显示方式.和P ...
- 从Unity中的Attribute到AOP(六)
本文将重点对Unity剩下常用的Attribute进行讲解,其他不常用的Attribute各位可以自行去官方文档查阅. 首先是UnityEngine命名空间下的. ColorUsage,这个主要作用于 ...
- 从Unity中的Attribute到AOP(五)
今天主要来讲一下Unity中带Menu的Attribute. 首先是AddComponentMenu.这是UnityEngine命名空间下的一个Attribute. 按照官方文档的说法,会在Compo ...
- 从Unity中的Attribute到AOP(四)
本篇我们将逐一讲解Unity中经常使用的Attribute(Unity对应的文档版本为2018.1b). 首先是Serializable,SerializeField以及NonSerialized,H ...
- 从Unity中的Attribute到AOP(三)
上一篇我们对系统的Attributes进行了MSIL代码的查看,了解到了其本质就是一个类的构造函数.本章我们将编写自己的Attributes. 首先我们定义书的属性代码,如下: [AttributeU ...
- 从Unity中的Attribute到AOP(二)
上一篇文章我们初步了解了一下Attributes的含义,并且使用系统自带的Attributes写了点代码.在进一步解剖我们的代码之前,我觉得有个概念可能需要巩固一下:什么是元数据? 我们知道C#代码会 ...
- 从Unity中的Attribute到AOP(一)
首先来看一下微软官方对Attributes(C#)的定义: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/conce ...
随机推荐
- [转]C# CancellationTokenSource 终止线程
我们在多线程中通常使用一个bool IsExit类似的代码来控制是否线程的运行与终止,其实使用CancellationTokenSource来进行控制更为好用,下面我们将介绍CancellationT ...
- 【JZOJ1913】【BZOJ2124】等差子序列
description 给一个1到N的排列{Ai},询问是否存在1<=p1<p2<p3<p4<p5<-<pLen<=N (Len>=3), 使得A ...
- vs code常用插件(python)
1.chinese 作用:vscode设置为中文. 使用方法:Ctrl+Shift+P:输入 "config":选择zh 2.python 作用:调试 3.autoDocstrin ...
- BZOJ 3569: DZY Loves Chinese II(线性基)
传送门 解题思路 首先构造出一个生成树,考虑不连接的情况.假设连通两点的非树边和树边都断掉后不连通,那么可以给所有的非树边随机一个互不相同的值,然后树边的权值为过他两端点的非树边权值的异或和,这个可以 ...
- rsync和rsync后台模式
注意(有软连接的rsync同步,-L可以把软链接里的当普通文件同步.-l 只同步软链接不同步软链接指向的目录或文件) rsync命令详解 rsync -a 归档模式 ,表示以递归方式传输文件,并保持所 ...
- java LogWriter
package org.rx.core; import lombok.Getter; import lombok.Setter; import lombok.SneakyThrows; import ...
- php打包下载文件
使用前请先开启:查看下php.ini里面的extension=php_zip.dll前面的分号有没有去掉; $zip=new \ZipArchive(); $zifile = 'download/' ...
- linux kafka进程挂了 自动重启
使用crontab,定时监控 kafka进程,发现挂了后重启. shell脚本如下: #!/bin/sh source /etc/profile proc_dir="/data/kafka& ...
- DCloud-Video:Html5 Video 实现方案
ylbtech-DCloud-Video:Html5 Video 实现方案 1.返回顶部 1.1. http://ask.dcloud.net.cn/article/569 1.2. 一. Html5 ...
- java 子类对象实例化的过程
大家往往听说 子类继承了父类就有了父类中的所有的非私有的属性,但是怎么就有了父类的属性了呢 ?且听下面分解 子类对象实例化的过程: 1 从结果上来看:(继承性) 子类继承了父类以后 就获取了父类中声 ...