我以前一篇文章介绍过XC#,用XC#可以非常方便的在一个Method上插入前置和后置条件的检查。XC#的实现是通过在编译时根据插入的指定Attribute动态在原有代码上加入相应的代码。
Lostinet的ContextBoundModel(以下简称CBM)是一个AOP.NET的框架,在CBM的基础上,可以非常方便的实现类似XC#的前置和后置条件检查,而且具有更大的灵活性,因为我们可以自己定制各种检查的条件。
下面示范在一个Person类的SetAge()方法和GetAge()方法上应用前置和后置条件:
public class Person : AspectObject
{
...
public void SetAge([AgeArg] Int32 age)
{
_iAge = age;
}
[AgeResult]
public Int32 GetAge()
{
return _iAge;
}
上面SetAge()方法需要检查传入的参数age是否如何年龄所需的要求(比如大于16岁,小于150岁),而GetAge()方法则需要检查返回的值是否如何要求。加在参数和方法上的两个Attribute,AgeArg和AgeResult都是实现了Lostinet.ContextBoundModel.IMessageHandlerAttribute接口的Attribute,所以可以用于标示拦截。
下面演示了AgeResultAttribute的实现:
[AttributeUsage(AttributeTargets.Method)]
public class AgeResultAttribute : Attribute, IMessageHandler, IMessageHandlerAttribute
{
...
public IMethodReturnMessage ProcessMessage(IMethodCallMessage mcm, AspectObjectProxy proxy, MessageHandlerQueue queue)
{
IMethodReturnMessage result = queue.InvokeNext(mcm, proxy);
if (Convert.ToInt32(result.ReturnValue) < 0)
{
throw new ApplicationException("返回值不能是" + result.ReturnValue.ToString());
}
return result;
}
}
在ProcessMessage()方法中,代码首先调用了“真实”的方法代码,然后对返回值进行检测。
如果感兴趣,点击这里下载这个示范项目的源码。在这里下载ContextBoundModel的最新的版本。
[本文中所有对ContextBoundModel的资料的引用,都得到了Lostinet的允许]