前言 1.引言 2.Aop概念 3.Aop實踐 4.總結 一、引言 對於初入行的小白來講,aop,ioc這兩個程式設計思想總是傻傻分不清,不知道是個什麼東東?別人再一談各種框架更是雲里霧裡。。。博主今天帶大家且先入個門,哈哈;) 二、Aop概念 AOP為Aspect Oriented Program ...
前言
1.引言
2.Aop概念
3.Aop實踐
4.總結
一、引言
對於初入行的小白來講,aop,ioc這兩個程式設計思想總是傻傻分不清,不知道是個什麼東東?別人再一談各種框架更是雲里霧裡。。。博主今天帶大家且先入個門,哈哈;)
二、Aop概念
AOP為Aspect Oriented Programming的縮寫,譯為:面向切麵編程。通過預編譯方式和運行期動態代理實現程式功能的統一維護的一種技術。
三、Aop實踐
在開發中,相信大家都遇到過驗證用戶許可權的事情,那是不是需要在每個界面上都要加個判斷呢?假如通過驗證,就執行某某業務邏輯,不通過,就跳轉或者提示啊 怎麼怎麼樣。。。
示圖一
從程式設計的角度來考慮,驗證用戶 這件事情我們是不是可以分離出去呢,因為都是相同的嘛,減少重覆,也是在不修改源代碼的情況下動態統一添加功能;另一個方面可以 讓一個對象儘可能的多關註自己的業務邏輯。這對於建立一個松耦合、可復用、可擴展性的系統是非常有利的。
下麵介紹靜態代理和動態代理實現AOP。(IL編織實現AOP這篇暫時先不介紹。。。)
創建公用的Model類
public class User { public int Age { get; set; } public string Name { get; set; } }
代理模式 實現靜態代理
//代理模式 實現靜態代理 class DecoratorAop { public static void Show() { User user = new User { Age = 3, Name = "Michael" }; IUserProcesser processer = new UserProcesser(); processer.RegUser(user); IUserProcesser userProcesser = new UserProcesserDecorator(processer); userProcesser.RegUser(user); } public interface IUserProcesser { void RegUser(User user); } public class UserProcesser : IUserProcesser { public void RegUser(User user) { Console.WriteLine($"註冊用戶,年齡為{user.Age},姓名{user.Name}"); } } public class UserProcesserDecorator : IUserProcesser { public IUserProcesser userProcesser; public UserProcesserDecorator(IUserProcesser processer) { userProcesser = processer; } public void RegUser(User user) { BeforeProcess(); Console.WriteLine($"註冊用戶,年齡為{user.Age},姓名{user.Name}"); AfterProcess(); } public void BeforeProcess() { Console.WriteLine("方法執行前"); } public void AfterProcess() { Console.WriteLine("方法執行後"); } } } class Program { static void Main(string[] args) { DecoratorAop.Show(); Console.ReadLine(); } }View Code
使用.NET Remoting/RealProxy 實現動態代理
class ProxyAop { public static void Show() { User user = new User { Age = 3, Name = "Michael" }; UserProcessor userProcessor = TransparentProxy.Create<UserProcessor>(); userProcessor.RegUser(user); } /// <summary> /// 真實代理 /// </summary> /// <typeparam name="T"></typeparam> public class MyRealProxy<T> : RealProxy { private T tTarget; public MyRealProxy(T target) :base(typeof(T)) { tTarget = target; } public override IMessage Invoke(IMessage msg) { BeforeProcess(); IMethodCallMessage methodCallMessage = (IMethodCallMessage)msg; object returnValue= methodCallMessage.MethodBase.Invoke(this.tTarget, methodCallMessage.Args); AfterProcess(); return new ReturnMessage(returnValue,new object[0],0,null, methodCallMessage); } public void BeforeProcess() { Console.WriteLine("方法執行前"); } public void AfterProcess() { Console.WriteLine("方法執行後"); } } /// <summary> /// 透明代理 /// </summary> public static class TransparentProxy { public static T Create<T>() { T instance= Activator.CreateInstance<T>(); MyRealProxy<T> myRealProxy = new MyRealProxy<T>(instance); T transparentProxy= (T)myRealProxy.GetTransparentProxy(); return transparentProxy; } } public interface IUserProcessor { void RegUser(User user); } public class UserProcessor :MarshalByRefObject, IUserProcessor { public void RegUser(User user) { Console.WriteLine($"用戶已註冊,年齡{user.Age},姓名{user.Name}"); } } } class Program { static void Main(string[] args) { ProxyAop.Show(); Console.ReadLine(); } }View Code
使用Castle\DynamicProxy 實現動態代理
public class CastleProxyAop { public static void Show() { User user = new User { Age = 3, Name = "Michael" }; ProxyGenerator proxyGenerator = new ProxyGenerator(); MyInterceptor myInterceptor = new MyInterceptor(); UserProcessor userProcessor= proxyGenerator.CreateClassProxy<UserProcessor>(myInterceptor); userProcessor.RegUser(user); userProcessor.GetID(); } public interface IUserProcessor { void RegUser(User user); void GetID(); } public class UserProcessor : IUserProcessor { public virtual void RegUser(User user) { Console.WriteLine($"用戶已註冊,年齡{user.Age},姓名{user.Name}"); } public virtual void GetID() { Console.WriteLine($"這是1"); } } public class MyInterceptor : IInterceptor { public void Intercept(IInvocation invocation) { PreProceed(); invocation.Proceed(); PostProceed(); } public void PreProceed() { Console.WriteLine($"方法執行前"); } public void PostProceed() { Console.WriteLine($"方法執行後"); } } } class Program { static void Main(string[] args) { CastleProxyAop.Show(); Console.ReadLine(); } }View Code
使用Entlib\PLAB Unity實現動態代理
public class UnityAop { public static void Show() { User user = new User { Age = 3, Name = "Michael" }; IUnityContainer unityContainer = new UnityContainer(); //聲明一個容器 unityContainer.RegisterType<IUserProcessor, UserProcessor>(); //聲明unityContainer並註冊IUserProcessor unityContainer.AddNewExtension<Interception>().Configure<Interception>() .SetInterceptorFor<IUserProcessor>(new InterfaceInterceptor()); IUserProcessor userProcessor = unityContainer.Resolve<IUserProcessor>(); userProcessor.RegUser(user); } #region //特性對應的行為 public class UserHandler : ICallHandler { public int Order { get; set; } public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext) { User user = input.Inputs[0] as User; if(user.Age<1) { return input.CreateExceptionMethodReturn(new Exception("年齡小於1歲禁止入內")); } Console.WriteLine($"參數檢測無誤"); IMethodReturn methodReturn = getNext()(input, getNext); return methodReturn; } } public class LogHandler : ICallHandler { public int Order { get; set; } public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext) { User user = input.Inputs[0] as User; string message = $"年齡{user.Age},姓名{user.Name}"; Console.WriteLine($"日誌已記錄,message:{message},time:{DateTime.Now}"); return getNext()(input, getNext); } } public class ExceptionHandler : ICallHandler { public int Order { get; set; } public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext) { IMethodReturn methodReturn = getNext()(input, getNext); if(methodReturn.Exception==null) { Console.WriteLine("無異常"); } else { Console.WriteLine($"異常:{methodReturn.Exception.Message}"); } return methodReturn; } } #endregion #region //特性 public class UserHandlerAttribute : HandlerAttribute { public override ICallHandler CreateHandler(IUnityContainer container) { ICallHandler callHandler = new UserHandler { Order = this.Order }; return callHandler; } } public class LogHandlerAttribute : HandlerAttribute { public override ICallHandler CreateHandler(IUnityContainer container) { return new LogHandler { Order = this.Order }; } } public class ExceptionHandlerAttribute : HandlerAttribute { public override ICallHandler CreateHandler(IUnityContainer container) { ICallHandler callHandler = new ExceptionHandler { Order = this.Order }; return callHandler; } } #endregion #region //業務 [ExceptionHandlerAttribute(Order =3)] [LogHandlerAttribute(Order =2)] [UserHandlerAttribute(Order =1)] public interface IUserProcessor { void RegUser(User user); } public class UserProcessor : IUserProcessor { public void RegUser(User user) { Console.WriteLine($"用戶已註冊,年齡{user.Age},姓名{user.Name}"); } } #endregion } class Program { static void Main(string[] args) { UnityAop.Show(); Console.ReadLine(); } }View Code
四、總結
AOP的優點:
1.解耦,將日誌記錄,性能統計,安全控制,事務處理,異常處理等代碼從業務邏輯中分離出去,當這些行為改變時不影響業務邏輯。
2.將通用功能從業務邏輯中抽離出來,提高代碼復用性,靈活性,可擴展性。
AOP與OOP的區別:
OOP講究“一切皆為對象”,使用類將世間萬事萬物的狀態和行為模塊化,封裝繼承多態。
AOP是將切麵(Aspect)模塊化。縱向切入,對業務處理過程中的切麵進行提取,以獲得邏輯過程中各部分之間低耦合的隔離效果,使應用對象更加關註業務邏輯,實現解耦,提供程式靈活性及可擴展性。
適用場景:日誌記錄,性能統計,安全控制,事務處理,異常處理。
參考:
http://www.cnblogs.com/landeanfen/p/4782370.html
http://www.cnblogs.com/jin-yuan/p/3811077.html
http://wayfarer.cnblogs.com/articles/241024.html