链式调用 - 封装业务函数
用设计模式、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
        
        ,  
     
        
          可扩展
        
      
    


 
           
					 
					