链式调用 - 封装业务函数
用设计模式、AOP能将一个方法/函数包裹起来,并且插入额外的逻辑行为,不过动作比较大,不是很灵活,下面介绍一种链式调用方法来封装的代码,完成后能实现如下的链式调用:
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();
}
运行图:
注意:这个封装会对目标业务函数加入try/catch来得到业务是否成功执行。
实现起来比较简单,就是每个函数返回自身,如下:
public
static
class
Pipeline
//这里只实现了2个泛型,可以增加很多个(这点比较麻烦)
{
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;
}
}
最终返回的结果对象:
public
struct
PipelineResult<TOUT>
{
///
<summary>
///
目标核心函数返回值
///
</summary>
public
TOUT Result {
get
;
set
; }
///
<summary>
///
是否存在异常
///
</summary>
public
bool
ExceptionExists {
get
;
set
; }
///
<summary>
///
具体的异常
///
</summary>
public
Exception Exception {
get
;
set
; }
}
只有一个输入参数的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个输入参数的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;
}
}
支持更多输入参数的?不要返回值的?自己搞定吧。
尽管这个模式很简单,但是只要扩展一下,就能做简单的复合业务逻辑,比如xml文件来配置,最终组合成复合业务,很有潜力的一个模式。
自省推动进步,视野决定未来。
心怀远大理想。
为了家庭幸福而努力。
A2D科技,服务社会。
A2D Framework (Alpha)
QQ群:283016070,真材实料的.NET架构师
心怀远大理想。
为了家庭幸福而努力。
A2D科技,服务社会。
A2D Framework (Alpha)
- 1. Cache System(本地缓存与分布式缓存共存、支持Memcache和Redis、支持贴标签形式(类似Spring 3.x的Cache形式))
- 2. Event System(本地事件与分布式事件分发)
- 3. IoC(自动匹配功能,实例数量限制功能)
- 4. Sql Dispatcher System(支持ADO.NET及EF)
- 5. Session System(分布式Session系统)
- 6. 分布式Command Bus(MSMQ实现,解决4M限制,支持Session的读取)
- 7. 规则引擎
QQ群:283016070,真材实料的.NET架构师
分类:
A2D Framework
,
可扩展

