<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>

          .net core 中的經(jīng)典設(shè)計(jì)模式的應(yīng)用

          共 6601字,需瀏覽 14分鐘

           ·

          2020-08-30 10:02

          .net core 中的經(jīng)典設(shè)計(jì)模式的應(yīng)用

          Intro

          前段時(shí)間我們介紹了23種設(shè)計(jì)模式,今天來分享一下 .net core 源碼中我覺得比較典型的設(shè)計(jì)模式的應(yīng)用

          實(shí)例

          責(zé)任鏈模式

          asp.net core 中間件的設(shè)計(jì)就是責(zé)任鏈模式的應(yīng)用和變形,

          每個(gè)中間件根據(jù)需要處理請求,并且可以根據(jù)請求信息自己決定是否傳遞給下一個(gè)中間件,我也受此啟發(fā),封裝了一個(gè) PipelineBuilder 可以輕松構(gòu)建中間件模式代碼,可以參考這篇文章 https://www.cnblogs.com/weihanli/p/12700006.html

          中間件示例:

          app.UseStaticFiles();
          app.UseResponseCaching();app.UseResponseCompression();
          app.UseRouting();
          app.UseCors(builder => builder.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin());
          app.UseAuthentication();app.UseAuthorization();
          app.UseEndpoints(endpoints =>{ endpoints.MapControllers(); endpoints.MapControllerRoute(name: "areaRoute", "{area:exists}/{controller=Home}/{action=Index}"); endpoints.MapDefaultControllerRoute();});

          PipelineBuilder 實(shí)際示例:

          var requestContext = new RequestContext(){    RequesterName = "Kangkang",    Hour = 12,};
          var builder = PipelineBuilder.Create(context => { Console.WriteLine($"{context.RequesterName} {context.Hour}h apply failed"); }) .Use((context, next) => { if (context.Hour <= 2) { Console.WriteLine("pass 1"); } else { next(); } }) .Use((context, next) => { if (context.Hour <= 4) { Console.WriteLine("pass 2"); } else { next(); } }) .Use((context, next) => { if (context.Hour <= 6) { Console.WriteLine("pass 3"); } else { next(); } }) ;var requestPipeline = builder.Build();foreach (var i in Enumerable.Range(1, 8)){ Console.WriteLine(); Console.WriteLine($"--------- h:{i} apply Pipeline------------------"); requestContext.Hour = i; requestPipeline.Invoke(requestContext); Console.WriteLine("----------------------------"); Console.WriteLine();}

          建造者模式

          asp.net core 中的各種 BuilderHostBuilder/ConfigurationBuilder 等,這些 Builder 大多既是 Builder 又是 Director,Builder 本身知道如何構(gòu)建最終的 Product(Host/Configuration)

          var host = new HostBuilder()    .ConfigureAppConfiguration(builder =>    {        // 注冊配置        builder            .AddInMemoryCollection(new Dictionary()            {                {"UserName", "Alice"}            })            .AddJsonFile("appsettings.json")            ;    })    .ConfigureServices((context, services) =>    {        // 注冊自定義服務(wù)        services.AddSingleton();        services.AddTransient();        if (context.Configuration.GetAppSetting("XxxEnabled"))        {            services.AddSingleton();        }    })    .Build()    ;

          工廠模式

          依賴注入框架中有著大量的工廠模式的代碼,注冊服務(wù)的時(shí)候我們可以通過一個(gè)工廠方法委托來獲取服務(wù)實(shí)例,

          依賴注入的本質(zhì)就是將對象的創(chuàng)建交給 IOC 容器來處理,所以其實(shí) IOC 容器本質(zhì)就是一個(gè)工廠,從 IOC 中獲取服務(wù)實(shí)例的過程就是工廠創(chuàng)建對象的過程,只是會根據(jù)服務(wù)的生命周期來決定是創(chuàng)建新對象還是返回已有對象。

          services.AddSingleton(sp => new Svc2(sp.GetRequiredService(), "xx"));

          單例模式

          在 dotnet 中有一個(gè) TimeQueue 的類型,純正的餓漢模式的單例模式代碼

          class TimerQueue{    #region singleton pattern implementation
          // The one-and-only TimerQueue for the AppDomain. static TimerQueue s_queue = new TimerQueue();
          public static TimerQueue Instance { get { return s_queue; } }
          private TimerQueue() { // empty private constructor to ensure we remain a singleton. }
          #endregion
          // ...}

          https://referencesource.microsoft.com/#mscorlib/system/threading/timer.cs,49

          在 dotnet 源碼中還有一些懶漢式的單例模式

          使用 Interlocked 原子操作

          internal class SimpleEventTypes    : TraceLoggingEventTypes{    private static SimpleEventTypes instance;
          internal readonly TraceLoggingTypeInfo typeInfo;
          private SimpleEventTypes(TraceLoggingTypeInfo typeInfo) : base( typeInfo.Name, typeInfo.Tags, new TraceLoggingTypeInfo[] { typeInfo }) { this.typeInfo = typeInfo; }
          public static SimpleEventTypes Instance { get { return instance ?? InitInstance(); } }
          private static SimpleEventTypes InitInstance() { var newInstance = new SimpleEventTypes(TraceLoggingTypeInfo.Instance); Interlocked.CompareExchange(ref instance, newInstance, null); return instance; }}

          另外一個(gè)示例,需要注意,下面這種方式不能嚴(yán)格的保證只會產(chǎn)生一個(gè)實(shí)例,在并發(fā)較高的情況下可能不是同一個(gè)實(shí)例,這也可以算是工廠模式的一個(gè)示例

          static internal class ConfigurationManagerHelperFactory {    private const string ConfigurationManagerHelperTypeString = "System.Configuration.Internal.ConfigurationManagerHelper, " + AssemblyRef.System;
          static private volatile IConfigurationManagerHelper s_instance;
          static internal IConfigurationManagerHelper Instance { get { if (s_instance == null) { s_instance = CreateConfigurationManagerHelper(); }
          return s_instance; } }
          [ReflectionPermission(SecurityAction.Assert, Flags = ReflectionPermissionFlag.MemberAccess)] [SuppressMessage("Microsoft.Security", "CA2106:SecureAsserts", Justification = "Hard-coded to create an instance of a specific type.")] private static IConfigurationManagerHelper CreateConfigurationManagerHelper() { return TypeUtil.CreateInstance(ConfigurationManagerHelperTypeString); }}

          原型模式

          dotnet 中有兩個(gè)數(shù)據(jù)結(jié)構(gòu) Stack/Queue 這兩個(gè)數(shù)據(jù)都實(shí)現(xiàn)了 ICloneable 接口,內(nèi)部實(shí)現(xiàn)了深復(fù)制 來看 StackClone 方法實(shí)現(xiàn):

          public virtual Object Clone(){    Contract.Ensures(Contract.Result() != null);     Stack s = new Stack(_size);    s._size = _size;    Array.Copy(_array, 0, s._array, 0, _size);    s._version = _version;    return s;}

          詳細(xì)可以參考:https://referencesource.microsoft.com/#mscorlib/system/collections/stack.cs,6acda10c5f8b128e

          享元模式

          string intern(字符串池),以及 Array.Empty()/Array.Empty()

          策略模式

          asp.net core 中的認(rèn)證和授權(quán),我覺得就是策略模式的應(yīng)用,在使用 [Authorize] 的時(shí)候會使用默認(rèn)的 policy,也可以指定要使用的策略 [Authorize("Policy1")] 這樣就會使用另外一種策略 Policy1,policy 還是比較簡單的

          policy 是用來根據(jù)用戶的認(rèn)證信息來控制授權(quán)訪問的,而認(rèn)證則是根據(jù)當(dāng)前上下文(請求上下文、線程上下文、環(huán)境上下文等)的信息進(jìn)行認(rèn)證從而獲取用戶信息的過程

          而不同的認(rèn)證模式(Cookie/JWT/自定義Token等)其實(shí)是不同的處理方法,也就是策略模式中不同的算法實(shí)現(xiàn),指定哪種認(rèn)證模式,就是使用哪種算法實(shí)現(xiàn)來獲取用戶信息

          觀察者模式

          常使用事件(event)進(jìn)行解耦,外部代碼通過訂閱事件來解耦,實(shí)現(xiàn)對內(nèi)部狀態(tài)的觀察

          Process 類中有很多事件,可以用來捕獲另一個(gè)進(jìn)程中的輸出,錯(cuò)誤等

          public event DataReceivedEventHandler OutputDataReceived;
          public event DataReceivedEventHandler ErrorDataReceived;

          通常這兩個(gè)事件我們就可以獲取到另外一個(gè)進(jìn)程中的輸出信息,除此之外還有很多的類在使用事件,相信你也用過很多

          組合模式

          WPF、WinForm 中都有控件的概念,這些控件的設(shè)計(jì)屬于是組合模式的應(yīng)用,所有的控件都會繼承于某一個(gè)共同的基類, 使得單個(gè)對象和組合對象都可以看作是他們共同的基類對象

          迭代器模式

          c# 中定義了迭代器模式,原始定義:

          // 聚集抽象public interface IEnumerable{    /// Returns an enumerator that iterates through a collection.    /// An  object that can be used to iterate through the collection.    IEnumerator GetEnumerator();}
          // 迭代器抽象public interface IEnumerator{ /// Advances the enumerator to the next element of the collection. /// /// if the enumerator was successfully advanced to the next element; if the enumerator has passed the end of the collection. /// The collection was modified after the enumerator was created. bool MoveNext();
          /// Gets the element in the collection at the current position of the enumerator. /// The element in the collection at the current position of the enumerator. object Current { get; }
          /// Sets the enumerator to its initial position, which is before the first element in the collection. /// The collection was modified after the enumerator was created. void Reset();}

          Array 和 List 各自實(shí)現(xiàn)了自己的迭代器,感興趣可以去看下源碼

          More

          .net core 中的設(shè)計(jì)模式應(yīng)用還有很多,不僅上面提到的這幾個(gè)模式,也不僅僅是我所提到的這幾個(gè)地方

          上面有一些示例是直接用的 dotnet framework 中的源碼,因?yàn)橛泻芏啻a都是類似的,用的 https://referencesource.microsoft.com 的源碼

          以上均是個(gè)人理解,如果有錯(cuò)誤還望指出,十分感謝,歡迎補(bǔ)充更多設(shè)計(jì)模式應(yīng)用的源碼實(shí)例

          Reference

          • https://github.com/dotnet/aspnetcore
          • https://github.com/dotnet/extensions
          • https://github.com/dotnet/corefx
          • https://github.com/dotnet/aspnetcore
          • https://github.com/dotnet/runtime


          瀏覽 37
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

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

          手機(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>
                    久久精品无码一区二区无码性色 | 免费在线观看黄片 | 影音先锋男人资源在线 | 亚洲在线资源 | 成人影久久久 |