也说AOP
前言
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(); } }
使用.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(); } }
使用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(); } }
使用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(); } }
四、总结
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