亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

實現一個對象驗證庫系列--3)Fluent以及擴展方法實現(請大神批評)

2019-11-14 13:52:42
字體:
來源:轉載
供稿:網友

前情回顧:

上一篇 2) 驗證器實現 簡單描述了下驗證器的簡單實現

本文將說說Fluent方式的實現,歡迎大神們指點指點

 

3) Fluent以及擴展方法實現

我們按照之前 Fluent 的設想以及我們解耦的方式,所以我們先實現一個創建驗證器創建者的靜態類:

public static class Validation{	public static IValidatorBuilder<T> NewValidatorBuilder<T>()  // 創建驗證器創建者	{		return Container.Resolve<IValidatorBuilder<T>>();	}	public static ValidateContext CreateContext(object validateObject,		ValidateOption option = ValidateOption.StopOnFirstFailure, params string[] ruleSetList)  // 創建驗證數據上下文參數	{		var result = Container.Resolve<ValidateContext>();		result.Option = option;		result.RuleSetList = ruleSetList;		result.ValidateObject = validateObject;		return result;	}}

 

我們接著實現 IValidatorBuilder 

public class ValidatorBuilder<T> : IValidatorBuilder<T>{	public ObservableCollection<IValidateRuleBuilder> Builders { get; set; }	public ValidatorBuilder()	{		Builders = new ObservableCollection<IValidateRuleBuilder>();	}	public IValidator Build()	// 最終build 方法	{		var result = Container.Resolve<IValidatorSetter>();		result.SetRules(Builders.Select(i => i.Build()));		return result;	}	public IFluentRuleBuilder<T, TPRoperty> RuleFor<TProperty>(Expression<Func<T, TProperty>> expression)  // 驗證規則創建者方法	{		ParamHelper.CheckParamNull(expression, "expression", "Can't be null");		var builder = Container.Resolve<IRuleBuilder<T, TProperty>>();		builder.SetValueGetter(expression);		Builders.Add(builder as IValidateRuleBuilder);		return builder;	}	public void RuleSet(string ruleSet, Action<IValidatorBuilder<T>> action)   // 規則分組標志設置方法	{		ParamHelper.CheckParamEmptyOrNull(ruleSet, "ruleSet", "Can't be null");		ParamHelper.CheckParamNull(action, "action", "Can't be null");		var upRuleSet = ruleSet.ToUpper();		var updateRuleSet = new NotifyCollectionChangedEventHandler<IValidateRuleBuilder>((o, e) =>		{			if (e.Action != NotifyCollectionChangedAction.Add) return;			foreach (var item in e.NewItems)			{				item.RuleSet = upRuleSet;			}		});		Builders.CollectionChanged += updateRuleSet;		action(this);		Builders.CollectionChanged -= updateRuleSet;	}	    // 規則分組標志設置方法這樣實現可以簡化設置的格式,讓代碼更清晰    // 比如    //	      var builder = Validation.NewValidatorBuilder<Student>();    //        builder.RuleSet("A", b =>    //        {    //            b.RuleFor(i => i.Name).NotNull()    //                    .Must(i=>i.Length > 10)    //                    .OverrideName("student name")    //                    .OverrideError("no name")    //              .ThenRuleFor(i => i.Age)    //                    .Must(i => i >= 0 && i <= 18)    //                    .OverrideName("student age")    //                    .OverrideError("not student");    //        });}

  

接著我們實現 IRuleBuilder:

public class RuleBuilder<T, TValue> : IRuleBuilder<T, TValue>{	public string RuleSet { get; set; }	public Func<object, TValue> ValueGetter { get; protected set; }	public Expression<Func<T, TValue>> ValueExpression { get; protected set; }	public string ValueName { get; set; }	public string Error { get; set; }	public IValidateRuleBuilder NextRuleBuilder { get; set; }	public Func<ValidateContext, bool> Condition { get; set; }	public Func<ValidateContext, string, string, IValidateResult> ValidateFunc { get; set; }	public void SetValueGetter(Expression<Func<T, TValue>> expression)  // 設置獲取值的方法	{		ValueExpression = expression;		var stack = new Stack<MemberInfo>();		var memberExp = expression.Body as MemberExpression;		while (memberExp != null)		{			stack.Push(memberExp.Member);			memberExp = memberExp.Expression as MemberExpression;		}		var p = Expression.Parameter(typeof(object), "p");		var convert = Expression.Convert(p, typeof(T));		Expression exp = convert;		if (stack.Count > 0)		{			while (stack.Count > 0)			{				exp = Expression.MakeMemberaccess(exp, stack.Pop());			}			ValueName = exp.ToString().Replace(convert.ToString() + ".", "");  // 設置默認的屬性名		}		else		{			ValueName = string.Empty;		}		ValueGetter = Expression.Lambda<Func<object, TValue>>(exp, p).Compile(); // 用表達式生成動態獲取不同對象的值的方法	}	public IFluentRuleBuilder<T, TProperty> ThenRuleFor<TProperty>(Expression<Func<T, TProperty>> expression) // 創建子級規則接口方法	{		var builder = Utils.RuleFor(expression);		NextRuleBuilder = builder as IValidateRuleBuilder;		return builder;	}	public IValidateRule Build() // 規則創建方法	{		var rule = Container.Resolve<IValidateRule>();		rule.ValueName = ValueName;		rule.Error = Error;		rule.ValidateFunc = ValidateFunc;		rule.Condition = Condition;		rule.RuleSet = RuleSet;		var nextBuilder = NextRuleBuilder;		if (nextBuilder != null)			rule.NextRule = nextBuilder.Build();		return rule;	}}

  

貌似我們完成了大部分了,但是好像哪里不對,

回憶一下,好像這個持有如何驗證邏輯方法的屬性沒有相關代碼處理

public class ValidateRule : IValidateRule{	public Func<ValidateContext, string, string, IValidateResult> ValidateFunc { get; set; }}

好吧,我們來建立一個基類先:

public abstract class BaseChecker<T, TProperty>{	public virtual IRuleMessageBuilder<T, TProperty> SetValidate(IFluentRuleBuilder<T, TProperty> builder) // 設置驗證規則邏輯方法	{		ParamHelper.CheckParamNull(builder, "builder", "Can't be null");		var build = builder as IRuleBuilder<T, TProperty>;		build.ValidateFunc = (context, name, error) =>		{			var value = build.ValueGetter(context.ValidateObject);			var result = Container.Resolve<IValidateResult>();			return Validate(result, value, name, error);		};		return build as IRuleMessageBuilder<T, TProperty>;	}	public IValidateResult GetResult()        // 獲取驗證結果實例對象	{		return Container.Resolve<IValidateResult>();	}	public void AddFailure(IValidateResult result, string name, object value, string error) // 添加錯誤信息	{		result.Failures.Add(new ValidateFailure()		{			Name = name,			Value = value,			Error = error		});	}	public abstract IValidateResult Validate(IValidateResult result, TProperty value, string name, string error); // 驗證規則邏輯接口}

  

再接著我們實現一個Must check 類:

public class MustChecker<T, TProperty> : BaseChecker<T, TProperty>{	private Func<TProperty, bool> m_MustBeTrue;	public MustChecker(Func<TProperty, bool> func)	{		ParamHelper.CheckParamNull(func, "func", "Can't be null");		m_MustBeTrue = func;	}	public override IValidateResult Validate(IValidateResult result, TProperty value, string name, string error)	{		if (!m_MustBeTrue(value))		{			AddFailure(result, name, value, error);		}		return result;	}}

  

然后我們接口綁定加上:

public static class Container{	public static ILifetimeScope CurrentScope { get; set; }	public static void Init(Action<ContainerBuilder> action)	{		ParamHelper.CheckParamNull(action, "action", "Can't be null");		Clear();		var builder = new ContainerBuilder();		action(builder);		var container = builder.Build();		CurrentScope = container.BeginLifetimeScope();	}	public static void Init()	{		Init(builder =>		{			builder.RegisterType<RuleSelector>().As<IRuleSelector>().SingleInstance();			builder.RegisterGeneric(typeof(RuleBuilder<,>)).As(typeof(IRuleBuilder<,>)).InstancePerDependency();			builder.Register(c => new ValidateContext() { RuleSelector = c.Resolve<IRuleSelector>() });			builder.RegisterType<ValidateRule>().As<IValidateRule>().InstancePerDependency();			builder.RegisterType<ValidateResult>().As<IValidateResult>().InstancePerDependency();			builder.RegisterGeneric(typeof(ValidatorBuilder<>)).As(typeof(IValidatorBuilder<>)).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>();	}}

  

再然后我們添加 must 的擴展方法:

public static class Syntax{	public static IRuleMessageBuilder<T, TProperty> Must<T, TProperty>(this IFluentRuleBuilder<T, TProperty> builder, Func<TProperty, bool> func)	{		return new MustChecker<T, TProperty>(func).SetValidate(builder);	}}

  

我們再添加一些消息設置相關的擴展方法:

public static class Syntax{	....	public static IRuleMessageBuilder<T, TProperty> When<T, TProperty>(this IRuleMessageBuilder<T, TProperty> builder, Func<TProperty, bool> func)	{		ParamHelper.CheckParamNull(func, "func", "Can't be null");		var ruleBuilder = builder as IRuleBuilder<T, TProperty>;		ruleBuilder.Condition = (context) =>		{			var value = ruleBuilder.ValueGetter(context.ValidateObject);			return func(value);		};		return builder;	}	public static IRuleMessageBuilder<T, TProperty> OverrideName<T, TProperty>(this IRuleMessageBuilder<T, TProperty> builder, string name)	{		(builder as IValidateRuleBuilder).ValueName = name;		return builder;	}	public static IRuleMessageBuilder<T, TProperty> OverrideError<T, TProperty>(this IRuleMessageBuilder<T, TProperty> builder, string error)	{		(builder as IValidateRuleBuilder).Error = error;		return builder;	}}

  

大功告成,我們現在就可以這樣使用了:

Container.Init();var builder = Validation.NewValidatorBuilder<Student>();builder.RuleSet("A", b =>{	b.RuleFor(i => i.Name).Must(i=>i.Length > 10)			.OverrideName("student name")			.OverrideError("no name")	  .ThenRuleFor(i => i.Age)			.Must(i => i >= 0 && i <= 18)			.OverrideName("student age")			.OverrideError("not student");});var v = builder.Build();var student = new BigStudent() { Age = 13, Name = "v" };var context = Validation.CreateContext(student);var result = v.Validate(context);Assert.IsNotNull(result);Assert.True(result.IsValid);Assert.True(result.Failures.Count == 0);

  

最后代碼和dll可以通過如下方法獲取:

nuget:https://www.nuget.org/packages/ObjectValidator/

github:https://github.com/fs7744/ObjectValidator

 

PS: 大神們快快給我些批評吧,冰天雪地跪求了


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美激情极品视频| 久久精品国产免费观看| 国产精品久久久久久久美男| 性欧美xxxx交| 日韩电影中文 亚洲精品乱码| 亚洲欧美激情四射在线日| 青草青草久热精品视频在线观看| 欧美日韩国产成人在线观看| 欧美裸体视频网站| 亚洲天堂久久av| 成人免费高清完整版在线观看| 久久久噜噜噜久久| 成人淫片在线看| 91精品久久久久| 亚洲精选在线观看| 中文字幕精品一区二区精品| 在线性视频日韩欧美| 欧美老女人性视频| 精品国产户外野外| 国产精品1234| 亚洲精品一区二区三区不| 51久久精品夜色国产麻豆| 日韩av免费一区| 国产精品久久久久久一区二区| 91久久久国产精品| 久久偷看各类女兵18女厕嘘嘘| 亚洲小视频在线观看| 91在线观看欧美日韩| 精品福利一区二区| 亚洲日本中文字幕免费在线不卡| 亚洲精品视频免费在线观看| 欧美区二区三区| 2019中文字幕全在线观看| 日韩在线视频一区| 欧美老妇交乱视频| 青青青国产精品一区二区| 欧洲日韩成人av| 最新91在线视频| 日韩亚洲欧美成人| 亚洲欧美日韩在线高清直播| 国产欧美一区二区三区在线看| 韩日精品中文字幕| 成人av色在线观看| 欧美国产一区二区三区| 国产91久久婷婷一区二区| 夜夜嗨av一区二区三区四区| 日韩欧美一区二区三区久久| 国产97人人超碰caoprom| 国产精品91久久久| 欧美与黑人午夜性猛交久久久| 精品国产电影一区| 久久在线精品视频| 欧美日产国产成人免费图片| 欧美黑人性生活视频| 91免费看片网站| 中文字幕亚洲精品| 国产一区二区欧美日韩| 精品久久久国产精品999| xxav国产精品美女主播| 日韩亚洲国产中文字幕| 亚洲影院在线看| 久久中国妇女中文字幕| yw.139尤物在线精品视频| 欧美第一黄色网| 日韩av一区二区在线观看| 国产精品福利在线观看网址| 精品国产一区二区三区久久| 亚洲精品www久久久久久广东| 日韩av免费在线观看| 欧美精品在线视频观看| 2024亚洲男人天堂| 亚洲区免费影片| 国产亚洲精品va在线观看| 亚洲精品国产suv| 亚洲视频在线视频| 久久久久九九九九| 欧美在线观看日本一区| 高潮白浆女日韩av免费看| 国产精品扒开腿爽爽爽视频| 成人h视频在线| 久久久中精品2020中文| 九九久久国产精品| 久热精品在线视频| 久久久精品欧美| 国产成人精品免高潮费视频| 欧洲精品久久久| 亚洲aaaaaa| 免费99精品国产自在在线| 狠狠色噜噜狠狠狠狠97| 日韩电影中文字幕一区| 97精品久久久中文字幕免费| 久久精品国产亚洲一区二区| 国产精品国产自产拍高清av水多| 国产成人短视频| 日韩在线免费观看视频| 亚洲国产免费av| 在线视频中文亚洲| 国产成人综合一区二区三区| 国产一区二区三区四区福利| 欧美性猛交xxxx免费看久久久| 午夜精品久久久久久久99热| 欧美一区二区色| 亚洲国产日韩欧美在线99| 亚洲国产精品va在线看黑人| 欧美猛交ⅹxxx乱大交视频| 亚洲精品欧美一区二区三区| 午夜精品一区二区三区视频免费看| 国产精品色午夜在线观看| 欧美日本黄视频| 国产精品自拍小视频| 丝袜情趣国产精品| 精品在线小视频| 日韩精品视频免费在线观看| 欧美性xxxx在线播放| 亚洲一区二区免费在线| 91精品国产高清自在线| 国内精品国产三级国产在线专| 久久免费福利视频| 5252色成人免费视频| 91香蕉嫩草影院入口| 精品国产欧美成人夜夜嗨| 久久精品国产视频| 久久亚洲精品网站| 最近2019免费中文字幕视频三| 欧美日本精品在线| 91精品视频在线播放| 精品久久久久久久大神国产| 91精品久久久久久久久久另类| 精品国产乱码久久久久酒店| 一本色道久久88综合日韩精品| 亚洲美女精品成人在线视频| 亚洲激情在线观看| 亚洲精品99久久久久| 欧美激情一区二区三区久久久| 大荫蒂欧美视频另类xxxx| 欧美性xxxxx极品| 午夜精品一区二区三区在线| 欧美成人三级视频网站| 亚洲第一av网站| 亚州成人av在线| 精品久久久中文| 久久精品视频导航| 中文字幕在线观看亚洲| 国产精品日韩一区| 高清欧美一区二区三区| 伊人久久精品视频| 日韩av黄色在线观看| 中文字幕无线精品亚洲乱码一区| 中文字幕国产精品久久| 国产热re99久久6国产精品| 欧美精品少妇videofree| www日韩中文字幕在线看| 久久久极品av| 日韩av手机在线看| 欧洲日韩成人av| 日韩成人在线视频网站| 中文字幕日韩在线播放| 欧美大片在线影院| 亚洲视频在线观看视频| 欧美电影第一页| 久久久久久久久久婷婷| 国产精自产拍久久久久久| 欧美一级淫片丝袜脚交| 亚洲xxxx妇黄裸体|