AOP
定义:在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
我的认为就是,在不更改原本核心业务的情况下,对原有的业务添加一些通用功能,这种形式的实现就是AOP。
实现
在C#中,实现AOP的方式有很多种,而在学习的时候,我们重点了解用装饰器模式、代理模式、.net内置的与第三方的AOP实现形式。接下来就一一观察他们的不同,并分析优缺点,最终选择更好扩展的、更通用的一个封装AOP的形式,在工作中熟练掌握。
在所有的实现中都会用到user实体类:
namespace _13_AOP
{
/// <summary>
/// 实体类
/// </summary>
public class User
{
public int Id { get; set; }
public string Name { get; set; }
}
}
装饰器模式实现AOP
装饰器模式的本质就是在不修改原有功能的情况下,为原有的功能动态的添加一些扩展功能。而用装饰模式来实现AOP是适合的。
代码实现
namespace _13_AOP.DecoratorForAOP
{
/// <summary>
/// IUserProcessor接口,提供核心功能规约
/// </summary>
interface IUserProcessor
{
void Register(User user);
}
}
namespace _13_AOP.DecoratorForAOP
{
/// <summary>
/// 实现IUserProcessor接口
/// </summary>
class UserProcessor : IUserProcessor
{
public void Register(User user)
{
Console.WriteLine("完成对用户的注册!!!");
}
}
}
namespace _13_AOP.DecoratorForAOP
{
/// <summary>
/// 对UserProcessor的装饰类
/// </summary>
class UserProcessorDecorator : IUserProcessor
{
public IUserProcessor IUser { get; set; }
// 装饰器模式不提供被装饰类的构造,需要在使用的时候动态传递
public UserProcessorDecorator(IUserProcessor userprocessor)
{
this.IUser = userprocessor;
}
/// <summary>
/// 为方法中调用被装饰的类方法,并完成在方法之前与之后的扩展
/// </summary>
/// <param name="user"></param>
public void Register(User user)
{
BeforMethord();
this.IUser.Register(user);
AfterMethord();
}
public void BeforMethord()
{
Console.WriteLine("方法之前的公共逻辑");
}
public void AfterMethord()
{
Console.WriteLine("方法之后的公共逻辑");
}
}
}
namespace _13_AOP
{
class Program
{
static void Main(string[] args)
{
User user = new User();
user.Id = 5;
Console.WriteLine("---------------代理模式静态AOP-----------------");
{
// 静态AOP,实则是装饰器模式
DecoratorForAOP.IUserProcessor userProcessor = new UserProcessorDecorator(new DecoratorForAOP.UserProcessor());
userProcessor.Register(user);
}
}
}
}
---------------代理模式静态AOP-----------------
方法之前的公共逻辑
完成对用户的注册!!!
方法之后的公共逻辑
介绍
用装饰器模式来实现AOP无疑是可行的,但是不是可用的。在业务功能繁多的情况下,用装饰器模式实现AOP会产生很多子类。这也是装饰器模式的缺点。如果过度使用,会使系统变的很复杂。
.net框架内置代理模式实现AOP
代理模式和装饰器模式很像,为了对原有业务扩展功能,用代理模式完全可以,甚至更好。因为他屏蔽了原本的核心业务功能的创建过程。
代码实现
namespace _13_AOP.ProxyForAOP
{
// 真实业务类,因为使用了框架,所以被代理的类必须继承MarshalByRefObject
class UserProcessor : MarshalByRefObject
{
public void Register(User user)
{
Console.WriteLine("完成对用户的注册!!!");
}
}
}
namespace _13_AOP.ProxyForAOP
{
/// <summary>
/// 要实现动态代理,这里需要是泛型,且需要继承框架提供的RealProxy类,这个类提供了代理的基本功能
/// </summary>
/// <typeparam name="T"></typeparam>
class MyRealProxy<T> : RealProxy
{
private T tTarget;
public MyRealProxy(T target) : base(typeof(T))
{
this.tTarget = target;
}
public override IMessage Invoke(IMessage msg)
{
// 前置方法
BeforeMethod(msg);
IMethodCallMessage message = (IMethodCallMessage)msg;
object returnValue = message.MethodBase.Invoke(this.tTarget, message.Args);
// 后置方法
AfterMethod(msg);
return new ReturnMessage(returnValue, new object[0], 0, null, message);
}
public void BeforeMethod(IMessage message)
{
Console.WriteLine("调用前");
}
public void AfterMethod(IMessage message)
{
Console.WriteLine("调用后");
}
}
}
namespace _13_AOP.ProxyForAOP
{
/// <summary>
/// 透明代理,对代理的创建
/// </summary>
public static class TransparentProxy
{
public static T Create<T>()
{
T instance = Activator.CreateInstance<T>();
MyRealProxy<T> realProxy = new MyRealProxy<T>(instance);
T t = (T)realProxy.GetTransparentProxy();
return t;
}
}
}
namespace _13_AOP
{
class Program
{
static void Main(string[] args)
{
User user = new User();
user.Id = 5;
Console.WriteLine("---------------动态代理AOP-----------------");
{
ProxyForAOP.UserProcessor userProcessor = TransparentProxy.Create<ProxyForAOP.UserProcessor>();
userProcessor.Register(user);
}
}
}
}
---------------动态代理AOP-----------------
调用前
完成对用户的注册!!!
调用后
介绍
这里用代理模式升级扩展的动态代理实现了AOP,用泛型+代理模式实现了对代理模式的扩展。这种可以针对所有的业务添加某种特定的公共功能。可以在工作中使用(但是需要手动调用,不是很方便,有更好的)。
第三方Castle代理实现AOP
需要引用第三方包:Castle.Core
代码实现
namespace _13_AOP.CastleForAOP
{
/// <summary>
/// 核心业务类,用castle来代理的类必须是公开可访问的
/// </summary>
public class UserProcessor
{
/// <summary>
/// 被代理的业务方法必须是virtual修饰的,否则无法完成扩展功能
/// </summary>
/// <param name="user"></param>
public virtual void Register(User user)
{
Console.WriteLine("完成对用户的注册!!!");
}
}
}
namespace _13_AOP.CastleForAOP
{
class MyCastleAOP : IInterceptor
{
public void Intercept(IInvocation invocation)
{
BeforeMethod(invocation);
invocation.Proceed();
AfterMethod(invocation);
}
public void BeforeMethod(IInvocation invocation)
{
Console.WriteLine("调用前");
}
public void AfterMethod(IInvocation invocation)
{
Console.WriteLine("调用后");
}
}
}
namespace _13_AOP
{
class Program
{
static void Main(string[] args)
{
User user = new User();
user.Id = 5;
Console.WriteLine("---------------Castle代理AOP-----------------");
{
// 框架的类,必须实现依赖。
ProxyGenerator proxyGenerator = new ProxyGenerator();
MyCastleAOP myCastleAOP = new MyCastleAOP();
CastleForAOP.UserProcessor userProcessor = proxyGenerator.CreateClassProxy<CastleForAOP.UserProcessor>(myCastleAOP);
userProcessor.Register(user);
}
}
}
}
---------------Castle代理AOP-----------------
调用前
完成对用户的注册!!!
调用后
介绍
实现起来很简单,调用起来复杂。但是可以使用,比较方便。
第三方Unity容器代理实现AOP
需要引用第三方包:Unity
代码实现
namespace _13_AOP.UnityForAOP
{
/// <summary>
/// 提供user接口,提供核心功能规约,接口必须是public的
/// </summary>
[UserHandler(Order = 1)]
public interface IUserBusiness
{
void Register(User user);
}
}
namespace _13_AOP.UnityForAOP
{
/// <summary>
/// 实现核心业务,完成对业务的实现
/// </summary>
public class UserBusiness : IUserBusiness
{
public void Register(User user)
{
Console.WriteLine("完成对用户的注册!!!");
}
}
}
namespace _13_AOP.UnityForAOP.Properties
{
public class UserHandler : ICallHandler
{
public int Order { get; set; }
public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
{
_13_AOP.User user = input.Inputs[0] as _13_AOP.User;
if (user.Id<5)
{
return input.CreateExceptionMethodReturn(new System.Exception("Id不能小于5!!!"));
}
System.Console.WriteLine("参数检查无误");
// 委托的调用方式
IMethodReturn methodReturn = getNext()(input, getNext);
return methodReturn;
}
}
}
namespace _13_AOP.UnityForAOP.Properties
{
public class UserHandlerAttribute : HandlerAttribute
{
public override ICallHandler CreateHandler(IUnityContainer container)
{
ICallHandler callHandler = new UserHandler()
{
Order = this.Order
};
return callHandler;
}
}
}
namespace _13_AOP
{
class Program
{
static void Main(string[] args)
{
User user = new User();
user.Id = 5;
Console.WriteLine("---------------Unity代理AOP-----------------");
{
// 声明一个容器并注册服务
IUnityContainer container = new UnityContainer();
container.RegisterType<IUserBusiness, UserBusiness>();
IUserBusiness userProcessor = container.Resolve<IUserBusiness>();
// 服务调用
userProcessor.Register(user);
// 为容器添加代理扩展
container.AddNewExtension<Interception>();
// 注册代理服务
container.RegisterType<IUserBusiness, UserBusiness>().Configure<Interception>().SetInterceptorFor<IUserBusiness>(new InterfaceInterceptor());
IUserBusiness Processor = container.Resolve<IUserBusiness>();
Processor.Register(user);
}
}
}
}
---------------Unity代理AOP-----------------
完成对用户的注册!!!
参数检查无误
完成对用户的注册!!!
介绍
这是最经常使用的,通过特性的方式为业务动态的添加一些通用功能。
ASP.NET MVC中过滤器实现AOP
在MVC中重点讲解,主要是通过特性+反射+统一入口来实现的。不多做介绍。