In the previous article, we introduced the interface of the validation verification module of commonlibrary, the class inheritance relationship, and the implementation of the validatorfluent chained call. Here we will continue to look at the example from the beginning, which is simple, I will not go into details about the design and implementation at a Glance. I will talk about some good ideas or methods that are worth learning. First of all, let's look at them:
code highlighting produced by actipro codehighlighter (freeware)
http://www.CodeHighlighter.com/
--> validation. isalpha ( " 123abc " , false )
validation. isalphanumeric ( " 123abc " , false , errors, "" )
validation. areequal T > (T1, t2);
Validation, validationextensions, and validationextensionsassertive. Static partial class validation is used in the three class files. The author implements the validationextensions of the parameter class ierrors for saving errors, and implements icomparable <t>, validationextensionsassertive, which is used for type comparison, is physically placed separately. This can be used as a reference in our usual design. Good physical placement makes our logic clearer and easier to maintain. In fact, it doesn't matter, check your understanding and actual coding requirements. This is very simple. You can see it.
In fact, if we want to be lazy, we can use the extension method for simple verification. "123abc". isnumericexp (), well, everything is ready for use. What are you waiting?
Public static bool isnumericexp (this string Str) {return RegEx. ismatch (STR, regexpatterns. Numeric );}
Here we will talk about this interface: icomparable <t>, which defines a general comparison method implemented by the value type or class to create a specific comparison method for the sort instance, if we want to use the type comparison method in the validation class, we must first implement
Icomparable <> the public int compareto (t) method of the generic interface. Compile the items we need to compare in this method, for example:
Public class user: icomparable <user> {Public String username {Get; set;} public datetime createdate {Get; set;} Public String email {Get; set ;} public String mobilephone {Get; Set ;}# region icomparable <user> member public int compareto (user other) {return this. username. compareto (Other. username) ;}# endregion} // call method: var errors = new validationresults (); validation. areequal <user> (user1, user2, errors, ""); printerrors (errors );
Lamda
// Implement public void example3_lamda () {var val = new validator (valevent => {int errcount = valevent. results. count; validation. isemail ("Kishore @", false, valevent. results, String. empty); validation. isurl ("http: // www", false, valevent. results, String. empty); validation. isphoneus ("111-111-111", false, valevent. results, String. empty); Return errcount = valevent. results. count;}); printerrors (Val. validate ();} // It is actually very simple. Let's take a look at the validator constructor. Public validator (func <validationevent, bool> validator) {_ validatorlamda = validator ;}
Here, we actually pass the generic delegate. What is the purpose of validationevent? I really don't want to understand here. In fact, as long as the action <ivalidationresults> can be implemented, why is the author writing so complicated? Simply add a validationevent to the parameter transfer white? For example:
Action <ivalidationresults> _ Action; Public validator (Action <ivalidationresults> action) {_ Action = action;} public ivalidationresults testaction () {_ lastvalidationresults = new validationresults (); if (_ Action! = NULL) {_ Action (_ lastvalidationresults);} return _ lastvalidationresults;} var T = new validator (errors => {validation. isemail ("Kishore @", false, errors, "email"); validation. isurl ("http: // www", false, errors, "url"); validation. isphoneus ("111-111-111", false, errors, "phone") ;}); T. testaction ();
The implementation of ruleslist verification is the same as that of Lamda verification. A list <validationruledef> is added to save the func <validationevent, bool> set ~!
Mvalidator custom Verification
Public void example6_custom () {comlib. ivalidator validator = new mycustomuseridvalidator ("admin"); ivalidationresults errors = new validationresults (); printerrors (validator. validate (); printerrors (validator. validate (errors); printerrors (validator. validatetarget ("poweruser01"); print ("both", validator. validate ("poweruser01", errors);} public class mycustomuseridvalidator: validator {// <summary> // initialize the object to validate. /// </Summary> /// <Param name = "username"> </param> Public mycustomuseridvalidator (string username) {target = username ;} /// <summary> // do some M validation on a user name (string ). /// </Summary> /// <Param name = "validationevent"> </param> /// <returns> </returns> protected override bool validateinternal (validationevent) {string id = (string) validationevent. target; If (string. isnullorempty (ID) {validationevent. results. add ("must supply a userid. "); Return false;} id = ID. tolower (); If (ID = "admin" | id = "Administrator") {validationevent. results. add ("admin user name is reserved, you can not use it. "); Return false;} If (ID. length <2 | ID. length> 15) {validationevent. results. add ("must be between 2> = username <= 15. "); Return false;} return true ;}}
Once you see this, all the questions mentioned above will suddenly understand that all custom verification classes must inherit validator and override the validateinternal method. We can see that validate calls the validateinternal method, while the validateinternal method is used for post-processing, the previous reason why validationevent is used is to make all extensions use the same parameters and Methods. Such a design certainly makes the moduleCodeThe same style maximizes the code reuse rate, but you have to weigh it by yourself if it is suitable for you.
After carefully reading all the design and code implementation of this module, I found that it did a good job and made me very confident to apply it to the general class libraries of the company. Well, there are many more in the future, let's take a look at Rome which can be built in one day ~
----- The module analysis is stopped. When I write it to the following modules, I think:
at this point, I don't think it is necessary to go deep into the design of this generic class library. The code is almost the same, or there are some implementations that are worth studying, and I don't want to analyze them one by one, wasting time and putting them upside down. This is what we use ~ the coupling of each module in commnlibrary is too strong, and it is not easy to pull out the module separately. Many module projects cannot be used. If it is hard to get it, I think it will only destroy the existing code structure, so far, only the cache, collections, email, extensions, feeds, notifications, queue, types, validation, localization, exceptions, and utilities modules have been released for use separately, that's all ~