封装业务函数

链式调用 - 封装业务函数

用设计模式、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)
  • 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架构师

 

 

 

原文地址:https://www.cnblogs.com/Leo_wl/p/3627148.html