效果
原类(必须是MarshalByRefObject的派生类)
public class Person : MarshalByRefObject { public string Say(string word) { return $"Hello,{word}!"; }}
切片类
public class PersonAspect { [Around(typeof(string))] public void Say(JoinPoint joinPoint) { var args = joinPoint.args; Console.WriteLine("调用之前:收到了" + args[0]); var result = joinPoint.Procced(); Console.WriteLine("调用之后:结果是" + result); }}
使用
static void Main(string[] args) { Person p = (Person) new AopRealProxy(typeof(Person), null, typeof(PersonAspect), null).GetTransparentProxy(); p.Say("World"); Console.Read();}
输出结果
调用之前:收到了World调用之后:结果是Hello,World!
实现
定义JoinPoint(切点类)
using System;using System.Runtime.Remoting.Messaging;
namespace KanameFramework.Core.Aop {
/// <summary> /// 切点 /// </summary> public class JoinPoint {
public object[] args; private Func<IMethodReturnMessage> procced;
public IMethodReturnMessage MethodReturnMessage { get; private set; }
public JoinPoint(object[] args, Func<IMethodReturnMessage> procced) { this.args = args; this.procced = procced; }
/// <summary> /// 执行原方法 /// </summary> public object Procced() { MethodReturnMessage = procced.Invoke(); return MethodReturnMessage.ReturnValue; }
}
}
定义Attribute
using System;
namespace KanameFramework.Core.Aop.Attributes { /// <summary> /// 标记此方法为环绕通知 /// </summary> [AttributeUsage(AttributeTargets.Method)] public class AroundAttribute: Attribute {
/// <summary> /// 方法的参数列表,用于寻找(重载的)方法 /// </summary> public Type[] ArgTypes { get; private set; }
public AroundAttribute() { ArgTypes = new Type[0]; }
public AroundAttribute(params Type[] argTypes) { ArgTypes = argTypes; } }}
继承RealProxy,并实现基本功能
using KanameFramework.Core.Aop.Attributes;using System;using System.Linq;using System.Reflection;using System.Runtime.Remoting;using System.Runtime.Remoting.Channels;using System.Runtime.Remoting.Messaging;using System.Runtime.Remoting.Proxies;using System.Security.Permissions;
namespace KanameFramework.Core.Aop {
/// <summary> /// 提供动态代理的基本功能 /// </summary> public class AopRealProxy : RealProxy {
private string URI; private Type aspectType; private object aspectInstance;
/// <summary> /// 组合目标类和切面类 /// </summary> /// <param name="type">目标类</param> /// <param name="typeIns">目标类实例</param> /// <param name="aspectType">切面类</param> /// <param name="aspectIns">切面类实例</param> [PermissionSet(SecurityAction.LinkDemand)] public AopRealProxy(Type type,object typeIns,Type aspectType, object aspectIns) : base(type) { this.aspectType = aspectType; this.aspectInstance = aspectIns??Activator.CreateInstance(aspectType); URI = RemotingServices.Marshal((MarshalByRefObject)(typeIns??Activator.CreateInstance(type))).URI; }
[SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)] public override IMessage Invoke(IMessage message) {
//获取参数值 var properties = message.Properties; var methodName = (string)properties["__MethodName"]; var argTypes = (Type[])properties["__MethodSignature"]; var args = (object[])properties["__Args"];
//切面类匹配到的的方法 var matchAspectMethods = aspectType.GetMethods(BindingFlags.Public|BindingFlags.NonPublic|BindingFlags.Instance).Where(m=> { if (!m.Name.Equals(methodName)) return false; var attr = m.GetCustomAttribute<AroundAttribute>(); if (attr == null) return false; return attr.ArgTypes.SequenceEqual(argTypes); });
//确定执行前设置uri properties["__Uri"] = URI;
//切面类没有对应方法直接返回 if (matchAspectMethods.Count()<1) return (IMethodReturnMessage)ChannelServices.SyncDispatchMessage(message);
//交给切面类执行 var joinPoint = new JoinPoint(args, () => (IMethodReturnMessage)ChannelServices.SyncDispatchMessage(message)); matchAspectMethods.First().Invoke(aspectInstance, new object[] { joinPoint }); return joinPoint.MethodReturnMessage; } }}
评论