鏈?zhǔn)秸{(diào)用 - 封裝業(yè)務(wù)函數(shù)
用設(shè)計(jì)模式、AOP能將一個(gè)方法/函數(shù)包裹起來(lái),并且插入額外的邏輯行為,不過(guò)動(dòng)作比較大,不是很靈活,下面介紹一種鏈?zhǔn)秸{(diào)用方法來(lái)封裝的代碼,完成后能實(shí)現(xiàn)如下的鏈?zhǔn)秸{(diào)用:
public class BO { public bool Add( string msg) { Console.WriteLine( " Add " ); if (msg == null ) throw new Exception(); return true ; } } static void Main( string [] args) { BO bo = new BO(); Pipeline < string , bool > p = Pipeline.Wrap< string , bool > (bo.Add) .BeforeExecute(m =>Console.WriteLine( " before execute " )) .AfterExecute((m, n) => Console.WriteLine( " after execute1 " )) .AfterExecute((m, n) => Console.WriteLine( " after execute2 " )) .Success((m, n) => Console.WriteLine( " success " )) .Fail((m, n) => Console.WriteLine( " fail " )) .Final((m, n) => Console.WriteLine( " final " )); Console.WriteLine( " Result: " +p.Execute( " testing " ).Result); Console.WriteLine(); Console.WriteLine(); Console.WriteLine( " Result: " + p.Execute( null ).Result); Console.ReadKey(); }
?運(yùn)行圖:
?注意:這個(gè)封裝會(huì)對(duì)目標(biāo)業(yè)務(wù)函數(shù)加入try/catch來(lái)得到業(yè)務(wù)是否成功執(zhí)行。
實(shí)現(xiàn)起來(lái)比較簡(jiǎn)單,就是每個(gè)函數(shù)返回自身,如下:
public static class Pipeline //這里只實(shí)現(xiàn)了2個(gè)泛型,可以增加很多個(gè)(這點(diǎn)比較麻煩) { public static Pipeline<TIN, TOUT> Wrap<TIN, TOUT>(Func<TIN, TOUT> method) { Pipeline <TIN, TOUT> p = new Pipeline<TIN, TOUT> (method); return p; } public static Pipeline<TIN1, TIN2, TOUT> Wrap<TIN1, TIN2, TOUT>(Func<TIN1, TIN2, TOUT> method) { Pipeline <TIN1, TIN2, TOUT> p = new Pipeline<TIN1, TIN2, TOUT> (method); return p; } }
?
?最終返回的結(jié)果對(duì)象:
public struct PipelineResult<TOUT> { /// <summary> /// 目標(biāo)核心函數(shù)返回值 /// </summary> public TOUT Result { get ; set ; } /// <summary> /// 是否存在異常 /// </summary> public bool ExceptionExists { get ; set ; } /// <summary> /// 具體的異常 /// </summary> public Exception Exception { get ; set ; } }
?
?只有一個(gè)輸入?yún)?shù)的Wrapper:
public class Pipeline<TIN, TOUT> { private Func<TIN, TOUT> method2Execute; private List<Action<TIN>> beforeExecuteActions = new List<Action<TIN>> (); private List<Action<TIN, TOUT>> afterExecuteActions = new List<Action<TIN, TOUT>> (); private Action<TIN, TOUT> finalAction; private List<Action<TIN, TOUT>> successActions = new List<Action<TIN, TOUT>> (); private List<Action<TIN, TOUT>> failActions = new List<Action<TIN, TOUT>> (); public Pipeline(Func<TIN, TOUT> method) { this .method2Execute = method; } public Pipeline<TIN, TOUT> BeforeExecute(Action<TIN> action) { beforeExecuteActions.Add(action); return this ; } public Pipeline<TIN, TOUT> AfterExecute(Action<TIN, TOUT> action) { afterExecuteActions.Add(action); return this ; } public Pipeline<TIN, TOUT> Final(Action<TIN, TOUT> action) { this .finalAction = action; return this ; } public Pipeline<TIN, TOUT> Success(Action<TIN, TOUT> action) { successActions.Add(action); return this ; } public Pipeline<TIN, TOUT> Fail(Action<TIN, TOUT> action) { failActions.Add(action); return this ; } public PipelineResult<TOUT> Execute(TIN argument) { PipelineResult <TOUT> result = new PipelineResult<TOUT> (); foreach ( var action in this .beforeExecuteActions) action.Invoke(argument); try { result.Result = this .method2Execute.Invoke(argument); result.ExceptionExists = false ; result.Exception = null ; } catch (Exception ex) { result.ExceptionExists = true ; result.Exception = ex; } foreach ( var action in this .afterExecuteActions) action.Invoke(argument, result.Result); if (! result.ExceptionExists) { foreach ( var action in this .successActions) action.Invoke(argument, result.Result); } else { foreach ( var action in this .failActions) action.Invoke(argument, result.Result); } if ( this .finalAction != null ) this .finalAction.Invoke(argument, result.Result); return result; } }
?
支持2個(gè)輸入?yún)?shù)的Wrapper:
public class Pipeline<TIN1, TIN2, TOUT> { private Func<TIN1, TIN2, TOUT> method2Execute; private List<Action<TIN1, TIN2>> beforeExecuteActions = new List<Action<TIN1, TIN2>> (); private List<Action<TIN1, TIN2, TOUT>> afterExecuteActions = new List<Action<TIN1, TIN2, TOUT>> (); private Action<TIN1, TIN2, TOUT> finalAction; private List<Action<TIN1, TIN2, TOUT>> successActions = new List<Action<TIN1, TIN2, TOUT>> (); private List<Action<TIN1, TIN2, TOUT>> failActions = new List<Action<TIN1, TIN2, TOUT>> (); public Pipeline(Func<TIN1, TIN2, TOUT> method) { this .method2Execute = method; } public Pipeline<TIN1, TIN2, TOUT> BeforeExecute(Action<TIN1, TIN2> action) { beforeExecuteActions.Add(action); return this ; } public Pipeline<TIN1, TIN2, TOUT> AfterExecute(Action<TIN1, TIN2, TOUT> action) { afterExecuteActions.Add(action); return this ; } public Pipeline<TIN1, TIN2, TOUT> Final(Action<TIN1, TIN2, TOUT> action) { this .finalAction = action; return this ; } public Pipeline<TIN1, TIN2, TOUT> Success(Action<TIN1, TIN2, TOUT> action) { successActions.Add(action); return this ; } public Pipeline<TIN1, TIN2, TOUT> Fail(Action<TIN1, TIN2, TOUT> action) { failActions.Add(action); return this ; } public PipelineResult<TOUT> Execute(TIN1 argument1, TIN2 argument2) { PipelineResult <TOUT> result = new PipelineResult<TOUT> (); foreach ( var action in this .beforeExecuteActions) action.Invoke(argument1, argument2); try { result.Result = this .method2Execute.Invoke(argument1, argument2); result.ExceptionExists = false ; result.Exception = null ; } catch (Exception ex) { result.ExceptionExists = true ; result.Exception = ex; } foreach ( var action in this .afterExecuteActions) action.Invoke(argument1, argument2, result.Result); if (! result.ExceptionExists) { foreach ( var action in this .successActions) action.Invoke(argument1, argument2, result.Result); } else { foreach ( var action in this .failActions) action.Invoke(argument1, argument2, result.Result); } if ( this .finalAction != null ) this .finalAction.Invoke(argument1, argument2, result.Result); return result; } }
?
支持更多輸入?yún)?shù)的?不要返回值的?自己搞定吧。?
盡管這個(gè)模式很簡(jiǎn)單,但是只要擴(kuò)展一下,就能做簡(jiǎn)單的復(fù)合業(yè)務(wù)邏輯,比如xml文件來(lái)配置,最終組合成復(fù)合業(yè)務(wù),很有潛力的一個(gè)模式。?
?
心懷遠(yuǎn)大理想。
為了家庭幸福而努力。
A2D科技,服務(wù)社會(huì)。
A2D Framework (Alpha)
- 1. Cache System(本地緩存與分布式緩存共存、支持Memcache和Redis、支持貼標(biāo)簽形式(類似Spring 3.x的Cache形式))
- 2. Event System(本地事件與分布式事件分發(fā))
- 3. IoC(自動(dòng)匹配功能,實(shí)例數(shù)量限制功能)
- 4. Sql Dispatcher System(支持ADO.NET及EF)
- 5. Session System(分布式Session系統(tǒng))
- 6. 分布式Command Bus(MSMQ實(shí)現(xiàn),解決4M限制,支持Session的讀取)
- 7. 規(guī)則引擎
QQ群:283016070,真材實(shí)料的.NET架構(gòu)師
?
?
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元
