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

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

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

      .Net Minimal APIs實現動態注冊服務

      .Net Minimal APIs實現動態注冊服務

      前言

      dotnet Minimal APIs實現動態注冊端點

      上一篇文章講解了在.Net Minimal APIs如何動態注冊端點,這篇文章來講解一下如何動態注冊服務

      文件層級結構如下:

      SharpIcoWeb
      ├── Endpoints
      │   ├── Internal
      │   │   ├── EndpointExtensions.cs
      │   │   ├── IEndpoint.cs
      │   ├── IcoEndpoints.cs
      │   ├── testEndpoints.cs
      ├── Program.cs
      

      需要修改EndpointExtensions動態注冊擴展類、IEndpoint端點注冊接口和Program.cs配置類來實現端點+服務的自動注冊,當然端點類也需要實現IEndpoint接口新增的方法。

      回顧

      在開始之前回顧一下如何動態注冊端點類:

      public static class EndpointExtensions
      {
          public static void MapAllEndpoints(this IEndpointRouteBuilder app)
          {
              var endpointTypes = Assembly.GetExecutingAssembly()
                  .GetTypes()
                  .Where(t => typeof(IEndpoint).IsAssignableFrom(t) && !t.IsInterface && !t.IsAbstract);
      
              foreach (var type in endpointTypes)
              {
                  type.GetMethod(nameof(IEndpoint.MapEndpoints))?
                  .Invoke(null, new object[] { app });
              }
          }
      }
      

      代碼詳解:

      主要注冊方法在擴展類中,主要分為2步。

      查找

      第一步: 查找所有實現了IEndpoint的類

      • Assembly.GetExecutingAssembly() - 獲取當前正在執行的程序集
      • GetTypes() - 獲取程序集中所有的類型
      • Where(...) - 篩選條件:
        • typeof(IEndpoint).IsAssignableFrom(t) - 類型必須實現 IEndpoint 接口
        • !t.IsInterface - 排除接口本身
        • !t.IsAbstract - 排除抽象類(不能被實例化的類)

      調用

      第二步:對每個端點類,調用它的靜態MapEndpoints方法

      • foreach - 遍歷前面找到的所有端點類型
      • type.GetMethod(nameof(IEndpoint.MapEndpoints)) - 獲取名為"MapEndpoints"的方法
        • nameof(IEndpoint.MapEndpoints) - 安全地獲取方法名
      • ?.Invoke(null, new object[] { app }) - 如果方法存在,則調用它
        • null - 表示是靜態方法(不需要實例)
        • new object[] { app } - 傳遞參數(IEndpointRouteBuilder

      開始實現

      IEndpoint接口

      首先在IEndpoint接口中添加用于服務注冊的接口成員。

      注意:之前的MapAllEndpoints重命名為UseEndpoints了,這個命名更加清晰。

      public interface IEndpoint
      { 
          static abstract void UseEndpoints(IEndpointRouteBuilder app);
          
          // 新增 IConfiguration configuration 參數可選
          static abstract void AddServices(IServiceCollection services, IConfiguration configuration);
      }
      

      端點類

      在每個端點類中實現AddServices方法。

      public class TestEndpoints : IEndpoint
      {
          public static void UseEndpoints(IEndpointRouteBuilder app)
          {
              // .....
          }
      
          public static void AddServices(IServiceCollection services, IConfiguration configuration)
          {
          }
      }
      
      public class IcoEndpoints: IEndpoint
      {
          public static void UseEndpoints(IEndpointRouteBuilder app)
          {
          	// .....
          }
      
          public static void AddServices(IServiceCollection services, IConfiguration configuration)
          {
              services.AddScoped<IFileService, FileService>();
          }
      }
      

      擴展類

      擴展方法是實現動態注冊的關鍵類。

      public static class EndpointExtensions
      {
          public static void UseEndpoints<TMarker>(this IEndpointRouteBuilder app)
          {
              UseEndpoints(app, typeof(TMarker));
          }
          
          public static void UseEndpoints(this IEndpointRouteBuilder app, Type typeMarker)
          {
              var endpointTypes = GetEndpointTypes(typeMarker);
      
              foreach (var type in endpointTypes)
              {
                  type.GetMethod(nameof(IEndpoint.UseEndpoints))?
                  .Invoke(null, new object[] { app });
              }
          }
      
          public static void AddEndpoints<TMarker>(this IServiceCollection services, IConfiguration configuration)
          {
              AddEndpoints(services, typeof(TMarker), configuration);
          }
          public static void AddEndpoints(this IServiceCollection services, Type typeMarker, IConfiguration configuration)
          {
              var endpointTypes = GetEndpointTypes(typeMarker);
      
              foreach (var endpointType in endpointTypes)
              {
                  endpointType.GetMethod(nameof(IEndpoint.AddServices))!
                      .Invoke(null, new object[] { services, configuration });
              }
          }
      
          private static IEnumerable<TypeInfo> GetEndpointTypes(Type typeMarker)
          {
              var endpointTypes = typeMarker.Assembly.DefinedTypes
                  .Where(x => !x.IsAbstract && !x.IsInterface && 
                              typeof(IEndpoint).IsAssignableFrom(x));
              return endpointTypes;
          }
      }
      

      這次在注冊的時候使用了泛型方法指定從哪個程序集找端點,如AddEndpoints<TMarker>

      其他的注冊端點的代碼和之前類似,可以看代碼詳解

      AddEndpoints用于動態注冊服務,與注冊端點不同的是注冊方法為AddServices,且傳遞的參數為services, configuration

       endpointType.GetMethod(nameof(IEndpoint.AddServices))!
                      .Invoke(null, new object[] { services, configuration });
      

      Program

      Program.cs中添加2行代碼就能完成端點和服務的注冊。

      builder.Services.AddEndpoints<Program>(builder.Configuration);
      
      app.UseEndpoints<Program>();
      

      總結

      動態注冊服務的核心也是通過反射找到注冊服務的靜態方法并調用它。

      使用TMarker泛型類型參數可以定位程序集,控制注冊服務的掃描范圍。

      posted @ 2025-07-17 10:04  妙妙屋(zy)  閱讀(604)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 国产精品v欧美精品∨日韩| 精品国产精品午夜福利| 公喝错春药让我高潮| 日韩中文字幕免费在线观看 | 望奎县| 午夜福利激情一区二区三区| 益阳市| a级黑人大硬长爽猛出猛进| 丁香五月亚洲综合在线国内自拍 | 日韩高清不卡免费一区二区| 精品久久久久久无码国产| 国产99久久精品一区二区| 思思99热精品在线| 激情综合五月丁香亚洲| 三都| 成人午夜av在线播放| 无码人妻精品一区二区三区蜜桃| 久久天天躁夜夜躁狠狠| 亚洲天堂男人影院| 国产人妻人伦精品婷婷| 丰满人妻被黑人猛烈进入| 国产精品久久国产三级国不卡顿| 国产成人高清精品亚洲一区| 欧美人与禽2o2o性论交| 2019国产精品青青草原| 自拍第一区视频在线观看| 亚洲国产韩国欧美在线| 日本a在线播放| 激情久久综合精品久久人妻| 中文字幕有码高清日韩| 国产精品一区在线蜜臀| 日本一区二区精品色超碰| 色综合久久久久综合体桃花网 | 午夜国产理论大片高清| 亚洲欧美综合人成在线 | 日本一区二区三区专线| 高颜值午夜福利在线观看| 久久亚洲精品天天综合网| free性开放小少妇| 人妻性奴波多野结衣无码| 亚洲天堂在线免费|