AOP(Aspect-Oriented Programming,面向切面的编程),它是可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术。它是一种新的方法论,它是对传统OOP编程的一种补充。 OOP是关注将需求功能划分为不同的并且相对独立,封装良好的类,并让它们有着属于自己的行为,依靠继承和多态等来定义彼此的关系;AOP是希望能够将通用需求功能从不相关的类当中分离出来,能够使得很多类共享一个行为,一旦发生变化,不必修改很多类,而只需要修改这个行为即可,跟业务逻辑分离开。 AOP是使用切面(aspect)将横切关注点模块化,OOP是使用类将状态和行为模块化。在OOP的世界中,程序都是通过类和接口组织的,使用它们实现程序的核心业务逻辑是十分合适。但是对于实现横切关注点(跨越应用程序多个模块的功能需求)则十分吃力,比如日志记录,验证,异常处理,身份认证和授权,缓存,性能监测,加密,压缩等。
Unity默认提供了三种拦截器来实现aop:TransparentProxyInterceptor、InterfaceInterceptor、VirtualMethodInterceptor。
TransparentProxyInterceptor:代理实现基于.NET Remoting技术,它可拦截对象的所有函数。缺点是被拦截类型必须派生于MarshalByRefObject类或接口
InterfaceInterceptor:只能对一个接口做拦截,好处时只要目标类型实现了指定接口就可以拦截,
VirtualMethodInterceptor:对virtual函数进行拦截。缺点是如果被拦截类型没有virtual函数则无法拦截,这个时候如果类型实现了某个特定接口可以改用InterfaceInterceptor.
示例:
public interface IPerson
{
void Say();
void Test();
void Test(string name);
}
public class Person : IPerson
{
<pre name="code" class="csharp"> [Behavior]
public virtual void Say() { Console.WriteLine("Person's Say Method is called!"); } public void Test() { Console.WriteLine("no argument"); } public void Test(string name) { Console.WriteLine("argument is " + name); } }
public class MyBehavior : ICallHandler
{
public int Order { get; set; }
public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
{
Console.WriteLine("before executing!");
if (input.MethodBase.Name == "Test")
{
if (input.Arguments.Count > 0 && input.Arguments.ParameterName(0) == "name")
{
Console.WriteLine("argument test");
}
}
var result = getNext()(input, getNext);//executed result
Console.WriteLine("after executing!");
return result;
}
}
public class BehaviorAttribute : HandlerAttribute
{
public override ICallHandler CreateHandler(Microsoft.Practices.Unity.IUnityContainer container)
{
return new MyBehavior();
}
}
static void Main(string[] args)
{
using (var container = new UnityContainer())
{
container.AddNewExtension<Interception>();
//1.TransparentProxyInterceptor
//container.Configure<Interception>().SetInterceptorFor<IPerson>(new TransparentProxyInterceptor());
//2.InterfaceInterceptor (使用1,2,3均可,这种侵入性最小)
container.Configure<Interception>().SetInterceptorFor<IPerson>(new InterfaceInterceptor());
//3.VirtualMethodInterceptor
//container.Configure<Interception>().SetInterceptorFor<Person>(new VirtualMethodInterceptor());
container.RegisterType<IPerson, Person>();
container.Resolve<IPerson>().Say();
}
Console.ReadLine();
}
或:
public interface IPerson
{
void Say();
void Test();
void Test(string name);
}
public class Person : IPerson
{
public virtual void Say()
{
Console.WriteLine("Person's Say Method is called!");
}
public void Test()
{
Console.WriteLine("no argument");
}
public void Test(string name)
{
Console.WriteLine("argument is " + name);
}
}
public class LogBehavior : IInterceptionBehavior
{
public bool WillExecute
{
get { return true; }
}
public IEnumerable<Type> GetRequiredInterfaces()
{
return Type.EmptyTypes;
}
public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
{
Console.WriteLine("before executing!");
var result = getNext()(input, getNext);//executed result
if (result.Exception != null)
{
Console.WriteLine("error:" + result.Exception.Message);
}
else
{
Console.WriteLine("execute successfully!");
}
Console.WriteLine("after executing!");
return result;
}
}
static void Main(string[] args)
{
using (var container = new UnityContainer())
{
<pre name="code" class="csharp"> container.AddNewExtension<Interception>();
container.RegisterType<IPerson, Person>(new Interceptor<InterfaceInterceptor>(), new InterceptionBehavior<LogBehavior>());
container.Resolve<IPerson>().Say(); } Console.ReadLine(); }