
本文共 25817 字,大约阅读时间需要 86 分钟。
AOP���Aspect Oriented Programming���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
AOP���������������������������������������������������������������������������������������������������������������������������������������������������
class RealA { public virtual string Pro { get; set; } public virtual void ShowHello(string name) { Console.WriteLine($"Hello!{name},Welcome!"); } }//��������� var a = new RealA(); a.Pro = "������"; a.ShowHello("������������");
������������������������������NEW������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������RealA������������������ProxyRealA���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������C#���������������������������������������������������������������virtual���
���������������
class ProxyRealA : RealA { public override string Pro { get { return base.Pro; } set { ShowLog("������Pro���������������������"); base.Pro = value; ShowLog($"������Pro���������������������:{value}"); } } public override void ShowHello(string name) { try { ShowLog("ShowHello���������������������"); base.ShowHello(name); ShowLog("ShowHello���������������������"); } catch(Exception ex) { ShowLog($"ShowHello���������������������������{ex.Message}"); } } private void ShowLog(string log) { Console.WriteLine($"{DateTime.Now.ToString()}-{log}"); } }//��������� var aa = new ProxyRealA(); aa.Pro = "������2"; aa.ShowHello("zuowenjun.cn");
������������������������������������ProxyRealA���������RealA���������������������ProxyRealA������RealA������ProxyRealA���������������������������������������������ProxyRealA������������������������������������������������������������������������������������������������RealA������������������������ProxyRealA������������������������������������������������������������������������������������������������������������������������������������ProxyRealA������������������������������������������ProxyRealA������������������������������������������������������������������������������
���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������RealA������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������AOP���������������������������������������
������������������������������������������������������������������AOP������������������������������������������������������������������������������������������RealA���������������������������������������������������������������������������������������������������
PostSharp:PostSharp���Aspect���������Attribute���������,���������������������������������OnMethodBoundaryAspect���������������������������������������������������OnEntry���OnExit������������������������������������AOP���������������������������������AOP������������������������������PostSharp���������������������������������������������������������EMIT������������������������������������PostSharp������������������������������������������������������������������������������������������������������������
������������EMIT���������������������Emit������������������������������������Castle.DynamicProxy���AOP������������������������������������������������������������������������������������������������������������������������������������������������������
using Castle.Core.Interceptor;using Castle.DynamicProxy;using NLog;using NLog.Config;using NLog.Win32.Targets;using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace ConsoleApp{ class Program { static void Main(string[] args) { ProxyGenerator generator = new ProxyGenerator(); var test = generator.CreateClassProxy(new TestInterceptor()); Console.WriteLine($"GetResult:{test.GetResult(Console.ReadLine())}"); test.GetResult2("test"); Console.ReadKey(); } } public class TestInterceptor : StandardInterceptor { private static NLog.Logger logger; protected override void PreProceed(IInvocation invocation) { Console.WriteLine(invocation.Method.Name + "���������,���������" + string.Join(",", invocation.Arguments)); } protected override void PerformProceed(IInvocation invocation) { Console.WriteLine(invocation.Method.Name + "���������"); try { base.PerformProceed(invocation); } catch (Exception ex) { HandleException(ex); } } protected override void PostProceed(IInvocation invocation) { Console.WriteLine(invocation.Method.Name + "������������������������" + invocation.ReturnValue); } private void HandleException(Exception ex) { if (logger == null) { LoggingConfiguration config = new LoggingConfiguration(); ColoredConsoleTarget consoleTarget = new ColoredConsoleTarget(); consoleTarget.Layout = "${date:format=HH\\:MM\\:ss} ${logger} ${message}"; config.AddTarget("console", consoleTarget); LoggingRule rule1 = new LoggingRule("*", LogLevel.Debug, consoleTarget); config.LoggingRules.Add(rule1); LogManager.Configuration = config; logger = LogManager.GetCurrentClassLogger(); //new NLog.LogFactory().GetCurrentClassLogger(); } logger.ErrorException("error",ex); } } public class TestA { public virtual string GetResult(string msg) { string str = $"{DateTime.Now.ToString("yyyy-mm-dd HH:mm:ss")}---{msg}"; return str; } public virtual string GetResult2(string msg) { throw new Exception("throw Exception!"); } }}
������������������������������������������ProxyGenerator���������������������������������������������������������������������������������������������������StandardInterceptor���TestInterceptor���������TestInterceptor���������������������������������������������generator.CreateClassProxy<TestA>(new TestInterceptor())������������������������������TestA���������������������������������������������������������������������������������������������������������������������������������������������Test������TestA������������������������������������������������������������������������������������������������������������������������������������������virtual������������������������������������������������������������
���������������������������������
������������������������+������Remoting������������������������������������������������������������������������������������������������������������������������
using System;using System.Collections.Generic;using System.Linq;using System.Runtime.Remoting.Activation;using System.Runtime.Remoting.Messaging;using System.Runtime.Remoting.Proxies;using System.Text;using System.Threading.Tasks;namespace ConsoleApp{ class Program { static void Main(string[] args) { var A = new AopClass(); A.Hello(); var aop = new AopClassSub("������������"); aop.Pro = "test"; aop.Output("hlf"); aop.ShowMsg(); Console.ReadKey(); } } [AopAttribute] public class AopClass : ContextBoundObject { public string Hello() { return "welcome"; } } public class AopClassSub : AopClass { public string Pro = null; private string Msg = null; public AopClassSub(string msg) { Msg = msg; } public void Output(string name) { Console.WriteLine(name + ",���������-->P:" + Pro); } public void ShowMsg() { Console.WriteLine($"������������������Msg������������������{Msg}"); } } public class AopAttribute : ProxyAttribute { public override MarshalByRefObject CreateInstance(Type serverType) { AopProxy realProxy = new AopProxy(serverType); return realProxy.GetTransparentProxy() as MarshalByRefObject; } } public class AopProxy : RealProxy { public AopProxy(Type serverType) : base(serverType) { } public override IMessage Invoke(IMessage msg) { if (msg is IConstructionCallMessage) { IConstructionCallMessage constructCallMsg = msg as IConstructionCallMessage; IConstructionReturnMessage constructionReturnMessage = this.InitializeServerObject((IConstructionCallMessage)msg); RealProxy.SetStubData(this, constructionReturnMessage.ReturnValue); Console.WriteLine("Call constructor"); return constructionReturnMessage; } else { IMethodCallMessage callMsg = msg as IMethodCallMessage; IMessage message; try { Console.WriteLine(callMsg.MethodName + "������������������"); object[] args = callMsg.Args; object o = callMsg.MethodBase.Invoke(GetUnwrappedServer(), args); Console.WriteLine(callMsg.MethodName + "������������������"); message = new ReturnMessage(o, args, args.Length, callMsg.LogicalCallContext, callMsg); } catch (Exception e) { message = new ReturnMessage(e, callMsg); } Console.WriteLine(message.Properties["__Return"]); return message; } } }}
���������������������������������
1.������������������������������AopClass���������������ContextBoundObject���������ContextBoundObject���������������������MarshalByRefObject���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
2.���������������ProxyAttribute������������������������AopAttribute���������������������������������������������������������CreateInstance������������CreateInstance���������������������������������������������������������������realProxy.GetTransparentProxy() ������������������������������������������AopProxy���������������������������������������������������
3.���������������AopProxy������������������������������������RealProxy������������������������������������Invoke���������������������������������������������������������������������������������������������������������������������������������������������������IMessage���������������������������������������������������
4.���������������������Aop���������������������AopAttribute������������������������������������������������1���������������������ContextBoundObject������������������������������������������������������������������������AopAttribute���������������������������������������������������������������������������������
���������������������������������
������������������������������������������RealProxy���������AOP���������������������
������������������+ ������������������������������������������������������������AOP������������������������������MVC���WEB API��������������������� ������������������MVC������������������������������MVC������������AOP���������������������������������������������������������������������������������������������������������������MVC���������������������������������������������Controller������Action���������������������������������������������������
���������������������
A.������������Controller���������������������������������
1.���������������������������������Controller������������
2.������Controller������������������1������������������Controller������������FindControllerType
3.���������������Controller���������Action���������������������������������FindAction
4.������Controller������������������
5.������Action���������������������������������������������������������������������������������������������������
6.������Controller������OnActionExecuting���������������������������������������������������������������ActionExecutingFilter
7.������Action������������������������
8.������Controller������OnActionExecuted���������������������������������������������������������������ActionExecutedFilter
9.������try catch���catch���������Controller������OnActionError���������������������������������������������������������ActionErrorFilter
10.���������������������
B.���������������������������������������
1.������������������������������������������AddExecRouteTemplate���������������������controller���action���������������������������������������������������������������������������routeTemplates���
2.���������������������������������������Controller������Action������������������ Run���������������������������������������������������������������������������������������������������������������������������OK���������������������Controller���Action���������������������������������������������Process���������������A���������������������������������������
���������������������MVC���������������������Action���������������������������������������ModelBinding���������������������������������������������������������������������AOP���������������������������������������������������������������������������������������������MVC���������ASP.NET MVC��������������� Console MVC,���������Winform MVC������
������������������������������������������������������������������������������������������������������
public abstract class Controller { public virtual void OnActionExecuting(MethodInfo action) { } public virtual void OnActionExecuted(MethodInfo action) { } public virtual void OnActionError(MethodInfo action, Exception ex) { } } public abstract class FilterAttribute : Attribute { public abstract string FilterType { get; } public abstract void Execute(Controller ctrller, object extData); } public class ActionExecutingFilter : FilterAttribute { public override string FilterType => "BEFORE"; public override void Execute(Controller ctrller, object extData) { Console.WriteLine($"���������{ctrller.GetType().Name}.ActionExecutingFilter���������������������������-{DateTime.Now.ToString()}"); } } public class ActionExecutedFilter : FilterAttribute { public override string FilterType => "AFTER"; public override void Execute(Controller ctrller, object extData) { Console.WriteLine($"���������{ctrller.GetType().Name}.ActionExecutedFilter���������������������������-{DateTime.Now.ToString()}"); } } public class ActionErrorFilter : FilterAttribute { public override string FilterType => "EXCEPTION"; public override void Execute(Controller ctrller, object extData) { Console.WriteLine($"���������{ctrller.GetType().Name}.ActionErrorFilter���������������������������-{DateTime.Now.ToString()}-Error Msg:{(extData as Exception).Message}"); } } public class AppContext { private static readonly Type ControllerType = typeof(Controller); private static readonly DictionarymatchedControllerTypes = new Dictionary (); private static readonly Dictionary matchedControllerActions = new Dictionary (); private Dictionary routeTemplates = new Dictionary (); public void AddExecRouteTemplate(string execRouteTemplate) { if (!Regex.IsMatch(execRouteTemplate, "{controller}", RegexOptions.IgnoreCase)) { throw new ArgumentException("������������������������������������{controller}"); } if (!Regex.IsMatch(execRouteTemplate, "{action}", RegexOptions.IgnoreCase)) { throw new ArgumentException("������������������������������������{action}"); } string[] keys = Regex.Matches(execRouteTemplate, @"(?<={)\w+(?=})", RegexOptions.IgnoreCase).Cast ().Select(c => c.Value.ToLower()).ToArray(); routeTemplates.Add(execRouteTemplate,keys); } public object Run(string execRoute) { //{controller}/{action}/{id} string ctrller = null; string actionName = null; ArrayList args = null; Type controllerType = null; bool findResult = false; foreach (var r in routeTemplates) { string[] keys = r.Value; string execRoutePattern = Regex.Replace(r.Key, @"{(? \w+)}", (m) => string.Format(@"(?<{0}>.[^/\\]+)", m.Groups["key"].Value.ToLower()), RegexOptions.IgnoreCase); args = new ArrayList(); if (Regex.IsMatch(execRoute, execRoutePattern)) { var match = Regex.Match(execRoute, execRoutePattern); for (int i = 0; i < keys.Length; i++) { if ("controller".Equals(keys[i], StringComparison.OrdinalIgnoreCase)) { ctrller = match.Groups["controller"].Value; } else if ("action".Equals(keys[i], StringComparison.OrdinalIgnoreCase)) { actionName = match.Groups["action"].Value; } else { args.Add(match.Groups[keys[i]].Value); } } if ((controllerType = FindControllerType(ctrller)) != null && FindAction(controllerType, actionName, args.ToArray()) != null) { findResult = true; break; } } } if (findResult) { return Process(ctrller, actionName, args.ToArray()); } else { throw new Exception($"������������������������������������������������������������������������������������������{execRoute}"); } } public object Process(string ctrller, string actionName, params object[] args) { Type matchedControllerType = FindControllerType(ctrller); if (matchedControllerType == null) { throw new ArgumentException($"������������������{ctrller}���Controller������"); } object execResult = null; if (matchedControllerType != null) { var matchedController = (Controller)Activator.CreateInstance(matchedControllerType); MethodInfo action = FindAction(matchedControllerType, actionName, args); if (action == null) { throw new ArgumentException($"���{matchedControllerType.FullName}���������������������������{actionName}������������������{args.Count()}������������������"); } var filters = action.GetCustomAttributes (true); List execBeforeFilters = new List (); List execAfterFilters = new List (); List exceptionFilters = new List (); if (filters != null && filters.Count() > 0) { execBeforeFilters = filters.Where(f => f.FilterType == "BEFORE").ToList(); execAfterFilters = filters.Where(f => f.FilterType == "AFTER").ToList(); exceptionFilters = filters.Where(f => f.FilterType == "EXCEPTION").ToList(); } try { matchedController.OnActionExecuting(action); if (execBeforeFilters != null && execBeforeFilters.Count > 0) { execBeforeFilters.ForEach(f => f.Execute(matchedController, null)); } var mParams = action.GetParameters(); object[] newArgs = new object[args.Length]; for (int i = 0; i < mParams.Length; i++) { newArgs[i] = Convert.ChangeType(args[i], mParams[i].ParameterType); } execResult = action.Invoke(matchedController, newArgs); matchedController.OnActionExecuted(action); if (execBeforeFilters != null && execBeforeFilters.Count > 0) { execAfterFilters.ForEach(f => f.Execute(matchedController, null)); } } catch (Exception ex) { matchedController.OnActionError(action, ex); if (exceptionFilters != null && exceptionFilters.Count > 0) { exceptionFilters.ForEach(f => f.Execute(matchedController, ex)); } } } return execResult; } private Type FindControllerType(string ctrller) { Type matchedControllerType = null; if (!matchedControllerTypes.ContainsKey(ctrller)) { var assy = Assembly.GetAssembly(typeof(Controller)); foreach (var m in assy.GetModules(false)) { foreach (var t in m.GetTypes()) { if (ControllerType.IsAssignableFrom(t) && !t.IsAbstract) { if (t.Name.Equals(ctrller, StringComparison.OrdinalIgnoreCase) || t.Name.Equals($"{ctrller}Controller", StringComparison.OrdinalIgnoreCase)) { matchedControllerType = t; matchedControllerTypes[ctrller] = matchedControllerType; break; } } } } } else { matchedControllerType = matchedControllerTypes[ctrller]; } return matchedControllerType; } private MethodInfo FindAction(Type matchedControllerType, string actionName, object[] args) { string ctrlerWithActionKey = $"{matchedControllerType.FullName}.{actionName}"; MethodInfo action = null; if (!matchedControllerActions.ContainsKey(ctrlerWithActionKey)) { if (args == null) args = new object[0]; foreach (var m in matchedControllerType.GetMethods(BindingFlags.Instance | BindingFlags.Public)) { if (m.Name.Equals(actionName, StringComparison.OrdinalIgnoreCase) && m.GetParameters().Length == args.Length) { action = m; matchedControllerActions[ctrlerWithActionKey] = action; break; } } } else { action = matchedControllerActions[ctrlerWithActionKey]; } return action; } }
������������������������������������Controller���������������TestController������������������������������������������������������������������������������������������������������������
public class TestController : Controller { public override void OnActionExecuting(MethodInfo action) { Console.WriteLine($"{action.Name}������������OnActionExecuting---{DateTime.Now.ToString()}"); } public override void OnActionExecuted(MethodInfo action) { Console.WriteLine($"{action.Name}������������OnActionExecuted--{DateTime.Now.ToString()}"); } public override void OnActionError(MethodInfo action, Exception ex) { Console.WriteLine($"{action.Name}���������OnActionError--{DateTime.Now.ToString()}:{ex.Message}"); } [ActionExecutingFilter] [ActionExecutedFilter] public string HelloWorld(string name) { return ($"Hello World!->{name}"); } [ActionExecutingFilter] [ActionExecutedFilter] [ActionErrorFilter] public string TestError(string name) { throw new Exception("������������������������������������"); } [ActionExecutingFilter] [ActionExecutedFilter] public int Add(int a, int b) { return a + b; } }
������������������������������������������������������������
class MVCProgram { static void Main(string[] args) { try { var appContext = new AppContext(); object rs = appContext.Process("Test", "HelloWorld", "������������"); Console.WriteLine($"Process���������������1���{rs}"); Console.WriteLine("=".PadRight(50, '=')); appContext.AddExecRouteTemplate("{controller}/{action}/{name}"); appContext.AddExecRouteTemplate("{action}/{controller}/{name}"); object result1 = appContext.Run("HelloWorld/Test/������������-zuowenjun.cn"); Console.WriteLine($"���������������1���{result1}"); Console.WriteLine("=".PadRight(50, '=')); object result2 = appContext.Run("Test/HelloWorld/������������-zuowenjun.cn"); Console.WriteLine($"���������������2���{result2}"); Console.WriteLine("=".PadRight(50, '=')); appContext.AddExecRouteTemplate("{action}/{controller}/{a}/{b}"); object result3 = appContext.Run("Add/Test/500/20"); Console.WriteLine($"���������������3���{result3}"); object result4 = appContext.Run("Test/TestError/������������-zuowenjun.cn"); Console.WriteLine($"���������������4���{result4}"); } catch (Exception ex) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine($"���������������{ex.Message}"); Console.ResetColor(); } Console.ReadKey(); } }
������������������ASP.NET MVC���������������������ASP.NET MVC���������URL���������������������������AppContext.Run ������������URL ���Process���������������������Controller���Action���������������������
���������������������������������������������������������������������������������������������������������������������������������������������������������������������������
MVC���������������������������
发表评论
最新留言
关于作者
