简介
若是你很熟悉面向方面编程(AOP),你就会知道给代码增长“切面”可使代码更清晰而且具备可维护性。可是AOP一般都依赖于第三方类库或者硬编码的.net特性来工做。虽然这些实现方式的好处大于它们的复杂程度,可是我仍然在寻找一种实现AOP的更为简单的方式,来试个人代码更为清晰。我将它们单独移出来,并命名为AspectF。
Aspect Oriented Programming (AOP)的背景
“切面”指的是那些在你写的代码中在项目的不一样部分且有相同共性的东西。它多是你代码中处理异常、记录方法调用、时间处理、从新执行一些方法等等的一些特殊方式。若是你没有使用任何面向切面编程的类库来作这些事情,那么在你的整个项目中将会遗留一些很简单而又重复的代码,它将使你的代码很难维护。例如,在你的业务逻辑层有些方法须要被记录,有些异常须要被处理,有些执行须要计时,数据库操做须要重试等等。因此,也许你会写出下面这样的代码。
拦截消息
public class AopAttribute : ProxyAttribute
{
public override MarshalByRefObject CreateInstance(Type serverType)
{
//AopProxy 就是拦截消息处理
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
{
object[] args = callMsg.Args;
//在这里调用要实现的方法
object o = callMsg.MethodBase.Invoke(GetUnwrappedServer(), args);
message = new ReturnMessage(o, args, args.Length, callMsg.LogicalCallContext, callMsg);
}
catch (Exception e)
{
message = new ReturnMessage(e, callMsg);
}
Console.WriteLine(message.Properties["__Return"].ToString());
return message;
}
}
}
调用的类
[AopAttribute]
public class AopClass : ContextBoundObject
{
public string Hello()
{
return "welcome";
}
public object GetName(string name)
{
return name + "说:此树是我栽,此路是我开,要想今后过,把命留下来";
}
}
class Program
{
static void Main(string[] args)
{
AopClass ap=new AopClass();
int k = 1;
ap.Hello();
k++;
ap.GetName("donsgheng");
Console.WriteLine(k);
}
}