鏈?zhǔn)秸{(diào)用 - 封裝業(yè)務(wù)函數(shù)
用設(shè)計(jì)模式、AOP能將一個(gè)方法/函數(shù)包裹起來,并且插入額外的邏輯行為,不過動(dòng)作比較大,不是很靈活,下面介紹一種鏈?zhǔn)秸{(diào)用方法來封裝的代碼,完成后能實(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來得到業(yè)務(wù)是否成功執(zhí)行。
實(shí)現(xià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è)模式很簡單,但是只要擴(kuò)展一下,就能做簡單的復(fù)合業(yè)務(wù)邏輯,比如xml文件來配置,最終組合成復(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)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元

