<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          如何使用C#在控制臺(tái)上動(dòng)態(tài)構(gòu)建中間件管道?

          共 6463字,需瀏覽 13分鐘

           ·

          2022-03-03 23:00


          如上圖所示:我們將會(huì)在下面文章上一步一步變形實(shí)現(xiàn)出這樣的功能。


          一、傻瓜式執(zhí)行演示

          首先建立控制臺(tái)項(xiàng)目,創(chuàng)建Begin() FirstMiddleware() SecondMiddleware() End() 三個(gè)函數(shù)

           1????????///?
          2????????///?開始執(zhí)行前
          3????????///?

          4????????public?static?void?Begin()
          5????????
          {
          6????????????Console.WriteLine("begin?executing");
          7????????}
          8
          9????????///?
          10????????///?執(zhí)行結(jié)束
          11????????///?

          12????????public?static?void?End()
          13????????
          {
          14????????????Console.WriteLine("end?executed");
          15????????}
          16
          17????????public?static?void?FirstMiddleware()
          18????????
          {
          19????????????Console.WriteLine("第一個(gè)中間件");
          20????????}
          21????????public?static?void?SecondMiddleware()
          22????????
          {
          23????????????Console.WriteLine("第二個(gè)中間件");
          24????????}

          按照如下順序執(zhí)行,并顯示結(jié)果

           1????????static?void?Main(string[]?args)
          2????????
          {
          3????????????//Console.WriteLine("Hello?World!");
          4????????????#region?傻瓜式演示中間件執(zhí)行方法
          5????????????Begin();
          6????????????FirstMiddleware();
          7????????????End();
          8????????????Console.WriteLine("-------------------");
          9????????????Begin();
          10????????????SecondMiddleware();
          11????????????End();
          12????????????#endregion
          13????????}



          二、封裝傻瓜式執(zhí)行函數(shù)

          這個(gè)Begin() End() 兩個(gè)方法會(huì)執(zhí)行多次,所以我們可以選擇封裝一下

           1????????///?
          2????????///?封裝一個(gè)執(zhí)行方法?減少重復(fù)代碼
          3????????///?入?yún)⒖梢詡鬟f一個(gè)無參數(shù)?無返回值函數(shù)?用內(nèi)置委托接受
          4????????///?

          5????????///?
          6????????public?static?void?CommonExecute(Action?function)
          7????????
          {
          8????????????Begin();
          9????????????function();
          10????????????End();
          11????????}

          如下調(diào)用,執(zhí)行結(jié)果和前文一樣

          1????????????#region?封裝傻瓜式執(zhí)行函數(shù)
          2????????????CommonExecute(FirstMiddleware);
          3????????????Console.WriteLine("-------------------");
          4????????????CommonExecute(SecondMiddleware);
          5????????????#endregion


          三、利用lambda變形簡化

          這里我們需要做個(gè)演變,就是將我們要執(zhí)行的CommonExecute()函數(shù)用lambda表達(dá)式包裹為另一個(gè)函數(shù)的參數(shù)傳遞;
          于是創(chuàng)建一個(gè)ExtraExecute() 函數(shù)

           1????????public?static?void?ExtraExecute(Action?function)
          2????????
          {
          3????????????try
          4????????????{
          5????????????????Console.WriteLine("try?here");
          6????????????????function();
          7????????????}
          8????????????catch?(Exception)
          9????????????{
          10
          11????????????????throw;
          12????????????}
          13????????}

          我們將包裹后的CommonExecute()作為入?yún)鬟f給ExtraExecute()調(diào)用,如下所示:

          1????????????ExtraExecute(()?=>?CommonExecute(FirstMiddleware));?//?執(zhí)行第一個(gè)中間件,先執(zhí)行ExtraExecute() 再執(zhí)行CommonExecute()
          2????????????Console.WriteLine("-----------");
          3????????????ExtraExecute(()?=>?CommonExecute(SecondMiddleware));?//?執(zhí)行第二個(gè)中間件


          通過觀察發(fā)現(xiàn)CommonExecute()ExtraExecute()方法簽名一樣,所以我們可以調(diào)換下兩者的執(zhí)行順序,如下所示:

          1????????????Console.WriteLine("-----------");
          2????????????//?更改中間件調(diào)用順序?先執(zhí)行CommonExecute()?再執(zhí)行ExtraExecute()
          3????????????CommonExecute(()?=>?ExtraExecute(FirstMiddleware));




          帶參創(chuàng)建中間件調(diào)用鏈

          我們剛剛演示了無參的中間件調(diào)用,現(xiàn)在給中間件執(zhí)行體增加入?yún)ⅲ略?strong style="font-size: inherit;color: inherit;line-height: inherit;">FirstPipe(string msg, Actionfunc) SecondPipe(string msg, Actionfunc) ThirdPipe(string msg, Actionfunc) 三個(gè)函數(shù),如下調(diào)用,核心原則就是將中間件執(zhí)行函數(shù)包裹成參數(shù)傳遞給下一個(gè)執(zhí)行的函數(shù)

          1?Action?pipe?=?(msg)?=>?ThirdPipe(msg,
          2????????????????????????????????????????????????????????(msg1)?=>?SecondPipe(msg1,
          3????????????????????????????????????????????????????????????(msg2)?=>?FirstPipe(msg2,?FirstMiddleware)));
          4?pipe("Hello?World");?//?調(diào)用



          動(dòng)態(tài)創(chuàng)建中間件管道模型

          從帶參創(chuàng)建中間件調(diào)用鏈上我們發(fā)現(xiàn),我們無法把這個(gè)管道變成動(dòng)態(tài)的,那么如何才能將中間件動(dòng)態(tài)傳入以及動(dòng)態(tài)改變調(diào)用順序呢?
          通過分析我發(fā)現(xiàn),一個(gè)管道執(zhí)行的最基本單元可以像下面這樣定義

           1????????public?abstract?class?DynamicPipeBase
          2????????{
          3????????????protected?readonly?Action<string>?_action;
          4
          5????????????public?DynamicPipeBase(Action<string>?action)
          6????????????
          {
          7????????????????this._action?=?action;
          8????????????}
          9????????????public?abstract?void?Handle(string?msg);?//?調(diào)用執(zhí)行中間件函數(shù)體
          10????????}

          然后定義三個(gè)函數(shù)繼承 DynamicPipeBase()

           1????????///?
          2????????///?第三個(gè)中間件
          3????????///?

          4????????public?class?ThirdSelfPipe?:?DynamicPipeBase
          5????????{
          6????????????public?ThirdSelfPipe(Action<string>?action):base(action)
          7????????????
          {
          8
          9????????????}
          10????????????public?override?void?Handle(string?msg)
          11????????????
          {
          12????????????????Console.WriteLine("Third?Pipe?Begin?executing");
          13????????????????_action(msg);
          14????????????????Console.WriteLine("Third?Pipe?End?executed");
          15????????????}
          16????????}
          17
          18????????public?class?SecondSelfPipe?:?DynamicPipeBase
          19????????{
          20????????????public?SecondSelfPipe(Action<string>?action)?:?base(action)
          21????????????
          {
          22
          23????????????}
          24????????????public?override?void?Handle(string?msg)
          25????????????
          {
          26????????????????Console.WriteLine("Second?Pipe?Begin?executing");
          27????????????????_action(msg);
          28????????????????Console.WriteLine("Second?Pipe?End?executed");
          29????????????}
          30????????}
          31
          32????????///?
          33????????///?第一個(gè)中間件
          34????????///?

          35????????public?class?FirstSelfPipe?:?DynamicPipeBase
          36????????{
          37????????????public?FirstSelfPipe(Action<string>?action)?:?base(action)
          38????????????
          {
          39
          40????????????}
          41????????????public?override?void?Handle(string?msg)
          42????????????
          {
          43????????????????Console.WriteLine("First?Pipe?Begin?executing");
          44????????????????_action(msg);
          45????????????????Console.WriteLine("First?Pipe?End?executed");
          46????????????}
          47????????}

          有了中間件,我們接著只需要構(gòu)建管道即可,如下所示

           1????????///?
          2????????///?存儲(chǔ)中間件:?List?_types;
          3????????///?生成中間件調(diào)用鏈:?GeneratePipe
          4????????///?構(gòu)建回調(diào):Build
          5????????///?

          6????????public?class?PipeBuilder
          7????????{
          8????????????protected?readonly?Action<string>?_mainAction;
          9????????????List?_types;
          10????????????public?PipeBuilder(Action<string>?mainAction)
          11????????????
          {
          12????????????????_mainAction?=?mainAction;
          13????????????????_types?=?new?List();
          14????????????}
          15????????????public?PipeBuilder?AddPipe(Type?type)
          16????????????
          {
          17????????????????_types.Add(type);
          18????????????????return?this;
          19????????????}
          20
          21????????????private?Action<string>?GeneratePipe(int?index)
          22????????????
          {
          23????????????????if(index==_types.Count-1)
          24????????????????{
          25????????????????????var?finalType=?(DynamicPipeBase)Activator.CreateInstance(_types[index],?_mainAction);
          26????????????????????return?finalType.Handle;
          27????????????????}
          28????????????????else
          29????????????????{
          30????????????????????var?childHalde=?GeneratePipe(index?+?1);
          31????????????????????return?((DynamicPipeBase)Activator.CreateInstance(_types[index],?childHalde)).Handle;
          32????????????????}?
          33
          34????????????}
          35
          36????????????public?Action<string>?Build()
          37????????????
          {
          38????????????????return?GeneratePipe(0);
          39????????????}
          40????????}

          最終我們?cè)谏隙苏{(diào)用:

          1????????????#region?動(dòng)態(tài)創(chuàng)建中間件管道模型
          2????????????Action<string>?pipeChain?=?new?PipeBuilder(MainAction)
          3????????????????.AddPipe(typeof(ThirdSelfPipe))?//?隨意添加多個(gè)中間件執(zhí)行單元
          4????????????????.AddPipe(typeof(SecondSelfPipe))
          5????????????????.AddPipe(typeof(FirstSelfPipe))
          6????????????????.Build();
          7????????????pipeChain("Hello?World");
          8????????????Console.WriteLine("-------------");
          9????????????#endregion


          這樣便實(shí)現(xiàn)了文章開頭展示的效果。


          瀏覽 68
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  啊啊啊啊啊啊啊网站 | www.苗条身,材骚气逼逼出水 | 亚洲在线观看中文字幕 | 日韩av有码 | 黄色三级毛片 |