<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Util應用框架核心(三) - 服務注冊器

      本節介紹服務注冊器的開發.

      如果你不需要擴展Util應用框架,直接跳過.

      當你把某些功能封裝到自己的類庫,并希望啟動時自動執行初始化代碼進行配置時,定義服務注冊器.

      服務注冊器概述

      服務注冊器是Util項目啟動時自動執行的代碼塊.

      Util應用框架的某些類庫使用服務注冊器進行配置,比如 Util.ObjectMapping.AutoMapper .

      當你引用 Util.ObjectMapping.AutoMapper 類庫,不需要進行任何配置就可以直接使用 AutoMapper 的基本功能.

      定義服務注冊器

      服務注冊器只需實現 Util.Infrastructure.IServiceRegistrar 接口,啟動器會掃描查找它.

      你可以把服務注冊器放在任何地方,不過放在約定的位置會更容易維護.

      約定: 服務注冊器名稱以 ServiceRegistrar 結尾,放到 Infrastructure 目錄中.

      IServiceRegistrar 接口代碼

      /// <summary>
      /// 服務注冊器
      /// </summary>
      public interface IServiceRegistrar {
          /// <summary>
          /// 排序號
          /// </summary>
          int OrderId { get; }
      
          /// <summary>
          /// 是否啟用
          /// </summary>
          bool Enabled {
              get;
          }
      
          /// <summary>
          /// 注冊服務,該操作在啟動開始時執行,如果需要延遲執行某些操作,可在返回的Action中執行,它將在啟動最后執行
          /// </summary>
          /// <param name="context">服務上下文</param>
          Action Register( ServiceContext context );
      }
      
      /// <summary>
      /// 服務上下文
      /// </summary>
      public class ServiceContext {
          /// <summary>
          /// 初始化服務上下文
          /// </summary>
          /// <param name="hostBuilder">主機生成器</param>
          /// <param name="assemblyFinder">程序集查找器</param>
          /// <param name="typeFinder">類型查找器</param>
          public ServiceContext( IHostBuilder hostBuilder, IAssemblyFinder assemblyFinder, ITypeFinder typeFinder ) {
              HostBuilder = hostBuilder ?? throw new ArgumentNullException( nameof( hostBuilder ) );
              AssemblyFinder = assemblyFinder ?? throw new ArgumentNullException( nameof( assemblyFinder ) );
              TypeFinder = typeFinder ?? throw new ArgumentNullException( nameof( typeFinder ) );
          }
      
          /// <summary>
          /// 主機生成器
          /// </summary>
          public IHostBuilder HostBuilder { get; }
      
          /// <summary>
          /// 程序集查找器
          /// </summary>
          public IAssemblyFinder AssemblyFinder { get; }
      
          /// <summary>
          /// 類型查找器
          /// </summary>
          public ITypeFinder TypeFinder { get; }
      }
      

      注冊服務

      Register 方法用于定義服務配置.

      Register 方法傳遞服務上下文 ServiceContext 參數,除了可以獲得主機生成器 IHostBuilder 外,還可以獲取類型查找器 ITypeFinder.

      你可以在服務注冊器中查找某些類型,并進行配置,比如查找 ISingletonDependency 接口的實現類,并配置單例依賴關系.

      Register 方法的返回類型是一個委托 Action.

      如果希望服務配置方法立即執行,返回 null.

      如果希望服務注冊器延遲到最后執行,返回委托.

      啟用服務注冊器

      只有已啟用的服務注冊器才會生效 .

      服務注冊器的執行順序

      通常服務注冊器用來配置服務的依賴注入關系,執行順序不太重要.

      不過如果你的服務注冊器依賴執行順序,需要在某些服務注冊器的前面或后面執行,可以設置排序號 OrderId.

      啟動器使用排序號對服務注冊器進行排序, OrderId 越小的先執行.

      此外,如果你需要將服務注冊器延遲到最后執行,可以讓 Register 方法返回委托.

      啟動器在執行服務注冊器 Register 方法后保存返回的委托實例列表.

      在執行委托實例之前,啟動器可能會執行其它操作.

      在之前的版本會配置依賴注冊器,不過它的作用有限,已經刪除,未來可能添加其它操作.

      禁用和啟用服務注冊器

      當引用包含服務注冊器的類庫,啟動時會自動運行初始化配置代碼.

      對于大部分場景都是預期行為.

      不過有些時候自動執行服務注冊器會導致問題,你需要禁用它.

      服務注冊器配置 Util.Infrastructure.ServiceRegistrarConfig 用于禁用和啟用服務注冊器.

      ServiceRegistrarConfig 使用 AppContext.SetSwitch 方法來完成禁用和啟用.

      /// <summary>
      /// 服務注冊器配置
      /// </summary>
      public class ServiceRegistrarConfig {
          /// <summary>
          /// 服務注冊器配置實例
          /// </summary>
          public static readonly ServiceRegistrarConfig Instance = new ();
      
          /// <summary>
          /// 禁用服務注冊器
          /// </summary>
          /// <param name="serviceName">服務注冊器名稱</param>
          public static void Disable( string serviceName ) {
              AppContext.SetSwitch( serviceName, false );
          }
      
          /// <summary>
          /// 啟用服務注冊器
          /// </summary>
          /// <param name="serviceName">服務注冊器名稱</param>
          public static void Enable( string serviceName ) {
              AppContext.SetSwitch( serviceName, true );
          }
      
          /// <summary>
          /// 是否啟用
          /// </summary>
          /// <param name="serviceName">服務注冊器名稱</param>
          public static bool IsEnabled( string serviceName ) {
              var result = AppContext.TryGetSwitch( serviceName, out bool isEnabled );
              if ( result && isEnabled == false )
                  return false;
              return true;
          }
      }
      

      直接傳遞服務名稱不太方便,可以在 ServiceRegistrarConfig 上定義擴展方法來禁用和啟用服務注冊器.

      服務注冊器范例

      下面以 Util.ObjectMapping.AutoMapper 類庫的服務注冊器為例進行說明.

      在服務注冊器定義服務名稱,一般使用帶命名空間的服務注冊器類名.

      設置排序號.

      Enabled屬性使用 ServiceRegistrarConfig 配置的 IsEnabled 方法,默認為啟用狀態,可以通過 ServiceRegistrarConfig 禁用它.

      Register 方法使用類型查找器查找所有實現了 IAutoMapperConfig 接口的配置實例并進行配置.

      創建 AutoMapper ObjectMapper 對象,并傳遞給 MapTo 擴展類.

      最后,通過主機生成器 ConfigureServices 配置 IObjectMapper 單例服務.

      /// <summary>
      /// AutoMapper服務注冊器
      /// </summary>
      public class AutoMapperServiceRegistrar : IServiceRegistrar {
          /// <summary>
          /// 獲取服務名
          /// </summary>
          public static string ServiceName => "Util.ObjectMapping.Infrastructure.AutoMapperServiceRegistrar";
      
          /// <summary>
          /// 排序號
          /// </summary>
          public int OrderId => 300;
      
          /// <summary>
          /// 是否啟用
          /// </summary>
          public bool Enabled => ServiceRegistrarConfig.IsEnabled( ServiceName );
      
          /// <summary>
          /// 注冊服務
          /// </summary>
          /// <param name="serviceContext">服務上下文</param>
          public Action Register( ServiceContext serviceContext ) {
              var types = serviceContext.TypeFinder.Find<IAutoMapperConfig>();
              var instances = types.Select( type => Reflection.CreateInstance<IAutoMapperConfig>( type ) ).ToList();
              var expression = new MapperConfigurationExpression();
              instances.ForEach( t => t.Config( expression ) );
              var mapper = new ObjectMapper( expression );
              ObjectMapperExtensions.SetMapper( mapper );
              serviceContext.HostBuilder.ConfigureServices( ( context, services ) => {
                  services.AddSingleton<IObjectMapper>( mapper );
              } );
              return null;
          }
      }
      

      服務注冊器配置擴展范例

      定義服務注冊器配置擴展

      在 ServiceRegistrarConfig 擴展特定的啟用和禁用方法,并封裝服務名.

      /// <summary>
      /// AutoMapper服務注冊器配置擴展
      /// </summary>
      public static class ServiceRegistrarConfigExtensions {
          /// <summary>
          /// 啟用AutoMapper服務注冊器
          /// </summary>
          /// <param name="config">服務注冊器配置</param>
          public static ServiceRegistrarConfig EnableAutoMapperServiceRegistrar( this ServiceRegistrarConfig config ) {
              ServiceRegistrarConfig.Enable( AutoMapperServiceRegistrar.ServiceName );
              return config;
          }
      
          /// <summary>
          ///禁用AutoMapper服務注冊器
          /// </summary>
          /// <param name="config">服務注冊器配置</param>
          public static ServiceRegistrarConfig DisableAutoMapperServiceRegistrar( this ServiceRegistrarConfig config ) {
              ServiceRegistrarConfig.Disable( AutoMapperServiceRegistrar.ServiceName );
              return config;
          }
      }
      

      使用服務注冊器配置擴展

      下面演示禁用 Util.ObjectMapping.Infrastructure.AutoMapperServiceRegistrar 服務注冊器.

      ServiceRegistrarConfig.Instance.DisableAutoMapperServiceRegistrar();
      builder.AsBuild().AddUtil();
      

      應在 AddUtil 方法之前禁用服務注冊器.

      posted @ 2023-10-31 19:52  何鎮汐  閱讀(488)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 色狠狠色婷婷丁香五月| 国产不卡一区二区精品| 亚洲男人第一无码av网| 国产免费播放一区二区三区| 人妻激情一区二区三区四区| 另类 专区 欧美 制服丝袜| 99riav国产精品视频| 蜜臀av色欲a片无人一区| 国产福利在线观看免费第一福利| 威海市| 日韩精品卡一卡二卡三卡四| 亚洲一区二区三区在线激情| 日韩成人一区二区三区在线观看| 亚洲精品久荜中文字幕 | 亚洲成人av一区二区| 性欧美暴力猛交69hd| 中文字幕乱偷无码av先锋蜜桃| 中文字幕av日韩有码| 极品人妻少妇一区二区三区| 久久这里只精品热免费99| 亚洲成色精品一二三区| 成年午夜无码av片在线观看| 国产成人精品视频网站| 亚洲欧美日韩综合久久久| 男人下部进女人下部视频| 国产午夜精品理论片久久影院| 蜜桃视频一区二区在线观看| 抚顺县| 日韩高清不卡免费一区二区| 国产在线播放专区av| 孟州市| 她也色tayese在线视频| 国产成人欧美日韩在线电影| 欧美综合天天夜夜久久| 在线天堂最新版资源| 久久久久久久一线毛片| 国产精品自拍午夜福利| 婷婷丁香五月深爱憿情网| 久久精品| 亚洲成a人无码av波多野| 国产精品一区二区三区性色|