用基於過濾器的方式處理,git
好比 : 提交訂單以前,要作以下的事:github
相似這樣把訂單加入到數據庫前的各類判斷,各類邏輯,均可以拆成一個一個的 Filter ,等全部的Filter 都執行完才作真正的後續邏輯。數據庫
這樣作 能夠 隨時扯下一個 邏輯,也能夠隨時加一個邏輯。 改一個邏輯不會影響其它邏輯。this
還會使代碼 更有條理。spa
-----------------------------------------------------------------------------------------------------------------------------------------------code
寫了一個類庫,使用時只要使用寫FIilter , 及最後的業務邏輯代碼就能夠了。blog
類庫已提到 Github( https://github.com/jinshuai/FilterRunner.Net)get
---------------------------------------------------------------------------------------------------------------------------------------------string
仍是慣例,直接上代碼:it
使用:
namespace Demo { class Program { static void Main(string[] args) { var user = new User() {Name="Tom",Age=68}; var runner = new FilterRunner.Runner<User>(user, p => { Console.WriteLine("Hello " +p.Name); return new FilterRunner.RunnerMessage() {IsSuccess=true,Message=" ok "}; }); //add filter runner.Filters.Add(new CheckUserRunnerFilter<User>()); //run var result= runner.Run(); Console.WriteLine("-----------"+result.Message+"---------------"); Console.ReadKey(); } } internal class User { public string Name { get; set; } public short Age { get; set; } } }
類庫:
/// <summary> /// 過慮器 /// </summary> public interface IRunnerFilter<in T> { /// <summary> /// 過濾器執行順序 /// </summary> int Sequence { get; set; } /// <summary> /// 過濾執行 /// </summary> /// <param name="targetObj"></param> /// <param name="isContinueRunNext"></param> /// <returns></returns> RunnerMessage Run(T targetObj, out bool isContinueRunNext); }
/// <summary> /// 返回消息 /// </summary> public class RunnerMessage { /// <summary> /// 執行是否成功 /// </summary> public bool IsSuccess { get;set;} /// <summary> /// 狀態碼 /// </summary> public int StatusCode { get;set;} /// <summary> /// 執行消息 /// </summary> public string Message { get;set;} /// <summary> /// 額外的數據 /// </summary> public Dictionary<string,object> DataExt { get;set;} }
/// <summary> /// 分部過濾執行器 /// </summary> /// <typeparam name="T">處理的對像類型 </typeparam> public class Runner<T> { protected T _targetObj = default(T); //執行對像 protected readonly Func<T,RunnerMessage> Executor = null; /// <summary> /// 過濾器 /// </summary> public List<IRunnerFilter<T>> Filters = new List<IRunnerFilter<T>>(); /// <summary> /// 構造 /// </summary> /// <param name="obj">要處理的對像</param> /// <param name="runner"></param> public Runner(T obj, Func<T,RunnerMessage> runner) { _targetObj = obj; Executor = runner; } /// <summary> /// 運行 /// </summary> /// <returns></returns> public virtual RunnerMessage Run() { var isContinueRunNext = true; var result = RunFilters(out isContinueRunNext); if (isContinueRunNext == false) { return result; } if (Executor == null) { throw new Exception("Runner is Null ! "); } return Executor(_targetObj); } /// <summary> /// 運行全部的 Filter /// </summary> /// <param name="isContinueRunNext"></param> /// <returns></returns> protected virtual RunnerMessage RunFilters(out bool isContinueRunNext) { isContinueRunNext = true; if (Filters == null || Filters.Count <= 0) { return null; } RunnerMessage result = null; Filters = Filters.Where(filter => filter != null).OrderBy(p => p.Sequence).ToList(); foreach (var filter in Filters) { result = filter.Run(this._targetObj, out isContinueRunNext); //若是不用繼續運行了就跳出 if (false == isContinueRunNext) { return result; } } return result; } }
ok, 就寫到這吧。