马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
听03很多师兄说主讲老师杭城方讲课很差就连旁听也没有去了)在三层模子中,我们一般会有一个Model层,用来和别的层传送数据。在给Model层赋值时,免不了要对数据举行某种划定规矩的考证,好比必要考证某个字段是不是同意为空,大概某个字段的值必需在一个局限内等等。固然我们能够在给字段赋值先考证,考证及格后才赋值给字段。这里我们次要讲怎样使用AOP完成Model层自已考证。
起首,我们必要利用Attribute特征来声明各类划定规矩。以下:
[FieldTypeDecimal(0,100)]
[NonEmpty]
publicdecimalPrice
{
get;
set;
}
下面的示例中,FieldTypeDecimal与NonEmpty就是两个自界说特征,NonEmpty用来标识Price不克不及为空,FieldTypeDecimal用来标识Price的赋值局限,[FieldTypeDecimal(0,100)]就暗示FieldTypeDecimal的值只能年夜于即是0或小于即是1000。
界说分离以下:
FieldTypeDecimal
///<summary>
///考证属性的值是不是年夜于或即是最小值,大概小于或即是最年夜值。
///</summary>
publicclassFieldTypeDecimal:Attribute
{
///<summary>
///是不是考证最小值
///</summary>
publicboolIsValidMinValue
{
get;
set;
}
///<summary>
///是不是考证最年夜值
///</summary>
publicboolIsValidMaxValue
{
get;
set;
}
privateintminValue;
publicintMinValue
{
get{returnminValue;}
set{minValue=value;}
}
privateintmaxValue;
publicintMaxValue
{
get{returnmaxValue;}
set{maxValue=value;}
}
publicFieldTypeDecimal(intminValue)
{
this.IsValidMinValue=true;
this.minValue=minValue;
}
publicFieldTypeDecimal(intminValue,intmaxValue)
{
this.IsValidMinValue=true;
this.IsValidMaxValue=true;
this.minValue=minValue;
this.maxValue=maxValue;
}
}
NonEmpty
///<summary>
///不成觉得空
///</summary>
publicclassNonEmpty:Attribute
{
publicNonEmpty(){}
}
注重:这两个类必定要承继Attribute。
然后将两个特征使用于某个Model类中,以下:
[ValidProxyAttribute]
publicclassSale_QuotationSheetDetail:ContextBoundObject
{
[FieldTypeDecimal(0,100)]
[NonEmpty]
publicdecimalPrice
{
get;
set;
}
}
注重下面Sale_QuotationSheetDetail类必定要承继ContextBoundObject,这个十分主要。
注重看下面的ValidProxyAttribute类,我们也有使用了一个自界说特征ValidProxyAttribute,这个特征以下:
///<summary>
///字段必要考证的标识
///</summary>
publicclassValidProxyAttribute:ProxyAttribute
{
publicoverrideMarshalByRefObjectCreateInstance(TypeserverType)
{
ValidProxyvalidProxy=newValidProxy(serverType);
returnvalidProxy.GetTransparentProxy()asMarshalByRefObject;
}
}
完成本文的功效最主要的部分来了,ValidProxy类。
ValidProxy类实在就是RealProxy的一个子类,我们能够重写Invoke办法,来拦阻Price属性的赋值办法"Set_Price"(任何类的属性的set操纵,实在都是一个Set_XXX的办法。),来考证值是不是满意划定规矩。
publicclassValidProxy:RealProxy
{
publicValidProxy(TypeserverType)
:base(serverType)
{}
publicoverrideIMessageInvoke(IMessagemsg)
{
if(msgisIConstructionCallMessage)
{
IConstructionCallMessageconstructCallMsg=msgasIConstructionCallMessage;
IConstructionReturnMessageconstructionReturnMessage=InitializeServerObject(constructCallMsg);
RealProxy.SetStubData(this,constructionReturnMessage.ReturnValue);
returnconstructionReturnMessage;
}
elseif(msgisIMethodCallMessage)
{
IMethodCallMessagecallMsg=msgasIMethodCallMessage;
object[]args=callMsg.Args;
IMessagemessage;
try
{
objectbaseObject=GetUnwrappedServer();
if(callMsg.MethodName.StartsWith("set_")&&args.Length==1)
{
stringmemberName=callMsg.MethodName.substring(4);
MemberInfoinfo=baseObject.GetType().GetMember(memberName)[0];
stringcolumnName=string.Empty;
if(info.IsDefined(typeof(IModel.FieldName),false))
{
IModel.FieldNamefieldName=(IModel.FieldName)info.GetCustomAttributes(typeof(IModel.FieldName),false)[0];
columnName=fieldName.Name;
}
ValidObservervalidObserver=newValidObserver(columnName);
IModel.IMessagemes;
if(info.IsDefined(typeof(IModel.NonEmpty),false))
{
mes=(IModel.IMessage)info.GetCustomAttributes(typeof(IModel.NonEmpty),false)[0];
validObserver.AddMessage(mes,args[0]);
}
if(info.IsDefined(typeof(IModel.FieldTypeDecimal),false))
{
mes=(IModel.IMessage)info.GetCustomAttributes(typeof(IModel.FieldTypeDecimal),false)[0];
validObserver.AddMessage(mes,args[0]);
}
validObserver.Valid();
}
objecto=callMsg.MethodBase.Invoke(baseObject,args);
message=newReturnMessage(o,args,callMsg.InArgCount,callMsg.LogicalCallContext,callMsg);
}
catch(Exceptione)
{
message=newReturnMessage(e,callMsg);
}
returnmessage;
}
else
returnmsg;
}
}
下面代码中的:
stringmemberName=callMsg.MethodName.substring(4);
MemberInfoinfo=baseObject.GetType().GetMember(memberName)[0];
stringcolumnName=string.Empty;
if(info.IsDefined(typeof(IModel.FieldName),false))
{
IModel.FieldNamefieldName=(IModel.FieldName)info.GetCustomAttributes(typeof(IModel.FieldName),false)[0];
columnName=fieldName.Name;
}
ValidObservervalidObserver=newValidObserver(columnName);
IModel.IMessagemes;
if(info.IsDefined(typeof(IModel.NonEmpty),false))
{
mes=(IModel.IMessage)info.GetCustomAttributes(typeof(IModel.NonEmpty),false)[0];
validObserver.AddMessage(mes,args[0]);
}
if(info.IsDefined(typeof(IModel.FieldTypeDecimal),false))
{
mes=(IModel.IMessage)info.GetCustomAttributes(typeof(IModel.FieldTypeDecimal),false)[0];
validObserver.AddMessage(mes,args[0]);
}
validObserver.Valid();
部分是我的划定规矩考证部分,人人的考证应当城市分歧,这里只是给人人一个参考。
注释一下下面几个关头办法或函数:
msgisIConstructionCallMessage假如以后实行的是机关函数
msgisIMethodCallMessage假如以后实行的自界说办法
object[]args=callMsg.Args;callMsg.Args暗示属性的值
callMsg.MethodName以后正在实行的办法的称号,(即set_XXXX办法)
GetUnwrappedServer()前往以后办法所属的工具(即完成中的Sale_QuotationSheetDetail类)
info.GetCustomAttributes为猎取类的自界说特征,能够参考示例:Asp.net中怎样查找类属性的自界说Attribute
如许,当我们在给Sale_QuotationSheetDetail的Price属性赋值时,城市主动实行ValidProxy类的Invoke办法,人人能够调试下,以增添了解。如果需要重新编写代码,几乎任何一门计算机语言都可以跨平台了,还用得着Java嘛,而且像PHP/C#等语言不需要修改代码都可以跨Windows/Linux。 |