AOP学习
一直以来对AOP的了解都是限制在理论层面,没有从实现的角度去做。在网上也看了许多列子,最后借鉴结合现有情况揉合所用
核心源码
方法属性部分
/// <summary>
/// 日志特性
/// </summary>
[AttributeUsage(AttributeTargets.Method,AllowMultiple =true,Inherited =true)]
public class LogAttribute:Attribute
{
public string FunctionCode { get; set; }
public ExecuteTime Sort { get; set; }
public int Order { get; set; }
}
/// <summary>
/// 权限特性
/// </summary>
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
public class PermissionsAttribute : Attribute
{
public string FunctionCode { get; set; }
public ExecuteTime Sort { get; set; }
public int Order { get; set; }
}
/// <summary>
/// 性能统计特性
/// </summary>
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
public class PerformanceAttribute : Attribute
{
public ExecuteTime Sort { get; set; }
public int Order { get; set; }
}
public enum ExecuteTime
{
BeforeRun,
AfterRun
}
public class AttributeInfo
{
public int Order { get; set; }
public ExecuteTime Time { get; set; }
public string AttributeName { get; set; }
public IList<System.Reflection.CustomAttributeNamedArgument> Datas { get; set; }
}
Remote代理部分
/// <summary>
/// 类 属性
/// </summary>
[AttributeUsage(AttributeTargets.Class,AllowMultiple =true,Inherited =true)]
public class AspectAttribute : ProxyAttribute
{
public override MarshalByRefObject CreateInstance(Type targetType)
{
AspectProxy realProxy = new AspectProxy(targetType);
return realProxy.GetTransparentProxy() as MarshalByRefObject;
}
}
public class AspectProxy : RealProxy
{
public AspectProxy(Type targetType)
: base(targetType) { }
public override IMessage Invoke(IMessage msg)
{
if (msg is IConstructionCallMessage)
{
IConstructionCallMessage constructCallMsg = msg as IConstructionCallMessage;
IConstructionReturnMessage constructionReturnMessage = InitializeServerObject((IConstructionCallMessage)msg);
RealProxy.SetStubData(this, constructionReturnMessage.ReturnValue);
return constructionReturnMessage;
}
else
{
IMethodCallMessage callMsg = msg as IMethodCallMessage;
IMessage message;
var attributes = callMsg.MethodBase.GetCustomAttributes(true);
var datas = callMsg.MethodBase.GetCustomAttributesData();
List<AttributeInof> list = new List<AttributeInof>();
foreach(Attribute attribute in attributes)
{
var data=datas.FirstOrDefault(x => x.AttributeType==attribute.GetType());
if (data == null) continue;
if(!data.NamedArguments.Any(x=>x.MemberName== "Order")|| !data.NamedArguments.Any(x => x.MemberName == "Sort"))
{
continue;
}
int Order = Convert.ToInt32(data.NamedArguments.FirstOrDefault(x => x.MemberName == "Order").TypedValue.Value);
ExecuteTime time = (ExecuteTime)Enum.ToObject(typeof(ExecuteTime), Convert.ToInt32(data.NamedArguments.FirstOrDefault(x => x.MemberName == "Sort").TypedValue.Value));
AttributeInof info = new AttributeInof();
info.Order = Order;
info.Time = time;
info.AttributeName = attribute.GetType().Name;
info.Datas = data.NamedArguments;
list.Add(info);
}
try
{
//执行前
BeforeRun(list, callMsg.Args);
object[] args = callMsg.Args;
object o = callMsg.MethodBase.Invoke(GetUnwrappedServer(), args);
//执行后
AfterRun(list, callMsg.Args);
list.Clear();
list = null;
message = new ReturnMessage(o, args, args.Length, callMsg.LogicalCallContext, callMsg);
}
catch (Exception e)
{
message = new ReturnMessage(e, callMsg);
}
return message;
}
}
private void BeforeRun(List<AttributeInof> list, object[] args)
{
var attributes = list.Where(x => x.Time == ExecuteTime.BeforeRun).OrderBy(x => x.Order);
if (attributes == null || attributes.Count() == 0)
{
return;
}
foreach(var attribute in attributes)
{
Dictionary<string, object> dict = new Dictionary<string, object>();
foreach(var data in attribute.Datas)
{
dict[data.MemberName] = data.TypedValue.Value;
}
Run(attribute.AttributeName, dict);
dict.Clear();
dict = null;
}
}
private void AfterRun(List<AttributeInof> list, object[] args)
{
var attributes = list.Where(x => x.Time == ExecuteTime.AfterRun).OrderBy(x => x.Order);
if (attributes == null || attributes.Count() == 0)
{
return;
}
foreach (var attribute in attributes)
{
Dictionary<string, object> dict = new Dictionary<string, object>();
foreach (var data in attribute.Datas)
{
dict[data.MemberName] = data.TypedValue.Value;
}
Run(attribute.AttributeName, dict);
dict.Clear();
dict = null;
}
}
void Run(string attributeName,Dictionary<string,object> dict)
{
//此处可做成插件 根据配置的插件反射执行
if (attributeName == "LogAttribute")
{
Log.Logs(dict);
}
else if (attributeName == "PermissionsAttribute")
{
Permission.Logs(dict);
}
else if (attributeName == "PerformanceAttribute")
{
Performance.Logs(dict);
}
}
}
处理部分
public class Log
{
public static void Logs(Dictionary<string,object> dict)
{
Console.WriteLine("日志记录");
}
}
public class Permission
{
public static void Logs(Dictionary<string, object> dict)
{
Console.WriteLine("权限");
}
}
public class Performance
{
public static void Logs(Dictionary<string, object> dict)
{
Console.WriteLine("性能统计");
}
}
Demo
[Aspect]
public class SimpleDemo : ContextBoundObject
{
[Log(FunctionCode ="Hello",Sort =ExecuteTime.BeforeRun,Order =0)]
[Permissions(FunctionCode = "Hello",Sort =ExecuteTime.BeforeRun,Order =1)]
[Performance(Sort =ExecuteTime.AfterRun,Order =0)]
public string Hello()
{
return "Hello World";
}
}
public class ChildDemo : SimpleDemo
{
[Performance(Sort = ExecuteTime.AfterRun, Order = 0)]
public void Say()
{
Console.WriteLine("我是 child");
}
}
测试
static void Main(string[] args)
{
SimpleDemo simple = new SimpleDemo();
simple.Hello();
ChildDemo child = new ChildDemo();
child.Hello();
child.Say();
Console.Read();
}