精灵巫婆 发表于 2015-1-16 14:19:16

使用AOP完成给Model类赋值考证

听03很多师兄说主讲老师杭城方讲课很差就连旁听也没有去了)在三层模子中,我们一般会有一个Model层,用来和别的层传送数据。在给Model层赋值时,免不了要对数据举行某种划定规矩的考证,好比必要考证某个字段是不是同意为空,大概某个字段的值必需在一个局限内等等。固然我们能够在给字段赋值先考证,考证及格后才赋值给字段。这里我们次要讲怎样使用AOP完成Model层自已考证。

起首,我们必要利用Attribute特征来声明各类划定规矩。以下:


publicdecimalPrice
{
get;
set;
}

下面的示例中,FieldTypeDecimal与NonEmpty就是两个自界说特征,NonEmpty用来标识Price不克不及为空,FieldTypeDecimal用来标识Price的赋值局限,就暗示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类中,以下:

publicclassSale_QuotationSheetDetail:ContextBoundObject
{


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);
stringcolumnName=string.Empty;
if(info.IsDefined(typeof(IModel.FieldName),false))
{
IModel.FieldNamefieldName=(IModel.FieldName)info.GetCustomAttributes(typeof(IModel.FieldName),false);
columnName=fieldName.Name;
}

ValidObservervalidObserver=newValidObserver(columnName);

IModel.IMessagemes;
if(info.IsDefined(typeof(IModel.NonEmpty),false))
{
mes=(IModel.IMessage)info.GetCustomAttributes(typeof(IModel.NonEmpty),false);
validObserver.AddMessage(mes,args);
}
if(info.IsDefined(typeof(IModel.FieldTypeDecimal),false))
{
mes=(IModel.IMessage)info.GetCustomAttributes(typeof(IModel.FieldTypeDecimal),false);
validObserver.AddMessage(mes,args);
}

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);
stringcolumnName=string.Empty;
if(info.IsDefined(typeof(IModel.FieldName),false))
{
IModel.FieldNamefieldName=(IModel.FieldName)info.GetCustomAttributes(typeof(IModel.FieldName),false);
columnName=fieldName.Name;
}

ValidObservervalidObserver=newValidObserver(columnName);

IModel.IMessagemes;
if(info.IsDefined(typeof(IModel.NonEmpty),false))
{
mes=(IModel.IMessage)info.GetCustomAttributes(typeof(IModel.NonEmpty),false);
validObserver.AddMessage(mes,args);
}
if(info.IsDefined(typeof(IModel.FieldTypeDecimal),false))
{
mes=(IModel.IMessage)info.GetCustomAttributes(typeof(IModel.FieldTypeDecimal),false);
validObserver.AddMessage(mes,args);
}

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。

分手快乐 发表于 2015-1-18 12:51:59

这也就是最近几年来随着各种新的后台技术的诞生,CGI应用在Internet上越来越少的原因。CGI方式不适合大访问量的应用。

兰色精灵 发表于 2015-1-25 09:21:43

主流网站开发语言之JSP:JSP和Servlet要放在一起讲,是因为它们都是Sun公司的J2EE(Java2platformEnterpriseEdition)应用体系中的一部分。

山那边是海 发表于 2015-2-2 21:34:06

这也就是最近几年来随着各种新的后台技术的诞生,CGI应用在Internet上越来越少的原因。CGI方式不适合大访问量的应用。

海妖 发表于 2015-2-8 06:35:21

那么,ASP.Net有哪些改进呢?

灵魂腐蚀 发表于 2015-2-24 22:18:09

JSP/Servlet虽然在国内目前的应用并不广泛,但是其前途不可限量。

精灵巫婆 发表于 2015-3-7 13:58:02

通过这次激烈的讨论,我从大家身上学到了太多,开阔了眼界,不管是支持我的还是骂我的,都感谢你们。

小妖女 发表于 2015-3-15 07:43:28

ASP在执行的时候,是由IIS调用程序引擎,解释执行嵌在HTML中的ASP代码,最终将结果和原来的HTML一同送往客户端。

不帅 发表于 2015-3-22 00:08:01

主流网站开发语言之PHP:PHP的全名非常有趣,它是一个巢状的缩写名称——“PHP:HypertextPreprocessor”,打开缩写还是缩写。PHP是一种HTML内嵌式的语言(就像上面讲的ASP那样)。而PHP独特的语法混合了C,Java,Perl以及PHP式的新语法。它可以比CGI或者Perl更快速地执行动态网页。
页: [1]
查看完整版本: 使用AOP完成给Model类赋值考证