Previously review:
Previous 1) interface introduction and general Idea Overview simply describes the code structure of the next library
This article will say the authenticator implementation, welcome the Great God guidance faster and better solution
2) Validator Implementation
We start with the validator that the user invokes, so we should do it first
public class Validator:ivalidator{public Ivalidateresult Validate (Validatecontext context) {}}
But aren't our validators without rules? Recall that we seem to have added an interface to the validator settings rule for Fluent design, so we should implement the validator like this:
public class Validator:ivalidatorsetter{private List<ivalidaterule> m_rules = new list<ivalidaterule> (); /save validation rules public void SetRules (ienumerable<ivalidaterule> rules) {paramhelper.checkparamnull (Rules, "rules", "Can ' t be null '); M_rules.addrange (Rules); Add validation rules}public Ivalidateresult Validate (Validatecontext context) {Paramhelper.checkparamnull (context, "context", " Can ' t be null "); var list = context. Rulesetlist;if (!list. Isemptyornull ()) {context. Rulesetlist = list. Where (i =!string. IsNullOrEmpty (i)). Select (i = I.toupper ()). ToArray ();} Process Validation Rule grouping flag filter list var rules = M_rules.where (I-= context. Ruleselector.canexecute (i, context)). ToArray ();//filter validation rule var result = container.resolve<ivalidateresult> (); if (!rules. Isemptyornull ()) {var tasks = rules. Select (i = Task.Factory.StartNew () = i.validate (context)). ToArray (); Task.waitall (tasks);//perform validation if (tasks). Any (i = i.isfaulted)) {var exceptions = tasks. Where (i = i.isfaulted). Select (i = I.exception); throw new aggregateexception (exceptions);} Exception for handling task var failures = tasks. Where (i = i.iscompleted). SelectMany (i = i.result.failures); Result. Merge (failures);//process validation results}return result;}}
We then implement the validation rules:
public class Validaterule:ivalidaterule{public Ivalidaterule nextrule {get; set;} public string RuleSet {get; set;} public string ValueName {get; set;} public string Error {get; set;} Public Func<validatecontext, bool> Condition {get; set;} Public Func<validatecontext, String, String, ivalidateresult> validatefunc {get; set;} Public Ivalidateresult Validate (Validatecontext context) {Paramhelper.checkparamnull (Validatefunc, "Validatefunc", " Can ' t be null "); Paramhelper.checkparamnull (Context, "context", "Can ' t be null"); Ivalidateresult result = null;if (Condition = = NULL | | Condition (context))//Determine the user's special filter condition {result = Validatebyfunc (context); Validation of the execution rule}else{result = container.resolve<ivalidateresult> ();} return result;} Public Ivalidateresult Validatebyfunc (Validatecontext context) {Ivalidateresult result = Validatefunc (context, ValueName, Error); The validation logic that executes the current rule is var nextrule = nextrule;if (nextrule! = null&& (Result). IsValid | | Context. Option = validateoptIon. Continue)//To determine if it is necessary to perform a child validation rule {var NextResult = nextrule.validate (context); Executes a child validation rule result. Merge (Nextresult.failures); Processing child validation results}return result;}}
Wait, it's like we haven't implemented a validation rule group flag filter, okay, let's do it.
public class ruleselector:iruleselector{public bool CanExecute (ivalidaterule rule, Validatecontext context) {return String. IsNullOrEmpty (rule. RuleSet) | | Context. Rulesetlist.isemptyornull ()? True:context. Rulesetlist.contains (rule. RuleSet);}}
We bind the current implementation with the interface to the container:
public static class Container{public static Ilifetimescope currentscope {get; set;} public static void Init (Action<containerbuilder> action) {Paramhelper.checkparamnull (Action, "Action", "Can ' t is Null "); Clear (), var builder = new Containerbuilder (), Action (builder), var container = Builder. Build (); CurrentScope = container. Beginlifetimescope ();} public static void Init () {init (builder =>{//binding Interface Builder. Registertype<ruleselector> (). As<iruleselector> (). SingleInstance (); builder. Register (c = new Validatecontext () {ruleselector = C.resolve<iruleselector> ()}); builder. Registertype<validaterule> (). As<ivalidaterule> (). Instanceperdependency (); builder. Registertype<validateresult> (). As<ivalidateresult> (). Instanceperdependency (); builder. Registertype<validator> (). As<ivalidatorsetter> (). Instanceperdependency ();});} public static void Clear () {var scope = currentscope;if (scope! = NULL) scope. Dispose ();} public static T resolve<t> () {RETUrn currentscope.resolve<t> ();}}
OK, let's try it out briefly:
Container.init (); Initial interface var v = new Validator (), var rule = new Validaterule () {Validatefunc = (c, name, error) =>{var f = new Validatefai Lure () {Name = Name,error = Error,value = C};return new Validateresult (new list<validatefailure> () {f});}}; V.setrules (New list<validaterule> () {rule});//Simple settings Verify var context = new Validatecontext () {ruleselector = new rule Selector ()};var result = v.validate (context);//try Assert.isnotnull (result); Assert.true (result. IsValid); Assert.isnotnull (result. Failures); Assert.AreEqual (0, result. Failures.count);
Well, there's no code to implement Fluent set validation rules, and now the whole looks really ugly.
Next:3) Fluent and extended method implementations
Implement an Object validation library series--2) Validator implementation (please God criticize)