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

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

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

      根據MediatR的Contract Messages自動生成Minimal WebApi接口

      大家好,我是失業(yè)在家,正在找工作的博主Jerry。今天給大家介紹一個能大大減少ASP.Net Minimal WebApi編碼量的方法。

      我們一般會把微服務的VO和DTO封裝成消息類,并作為WebApi的Request和Response參數進行網絡傳遞。

      如果使用MediatR,我們封裝的消息類就要實現 MediatR Contract 接口 IRequest<> 或者INotification,  例如我的代碼如下:

      namespace MediatRApplication.CategoryCRUD
      {
          public class CreateCategory : IRequest<CreateCategoryResult>
          {
              public string Message { get; set; }
          }
          public class CreateCategoryResult
          {
              public string Message { get; set; }
          }
      
          public class ReadCategory : IRequest<ReadCategoryResult>
          {
              public string Message { get; set; }
          }
          public class ReadCategoryResult
          {
              public string Message { get; set; }
          }
      
          public class UpdateCategory : IRequest<UpdateCategoryResult>
          {
              public string Message { get; set; }
          }
          public class UpdateCategoryResult
          {
              public string Message { get; set; }
          }
      
          public class DeleteCategory : IRequest
          {
              public string Message { get; set; }
          }
      }

      如上代碼是對Category業(yè)務實體進行CRUD操作封裝的DTO消息類,每個消息類都實現了MediatR的IRequest接口。有了消息類,就可以對每個消息類編寫處理器(Handler),以實現業(yè)務功能。

      有了消息類,就需要為每個消息類創(chuàng)建WebApi接口,以實現消息的Request和Response。WebAPI接口中沒有業(yè)務邏輯,只需要調用MediatR的Send方法將消息類發(fā)送給Handler即可。

      但是,由于消息類比較多,一個一個創(chuàng)建WebApi接口是一件費時費力,并且容易出錯的事情。作為一個架構師,是無法忍受程序員們干這些出力不討好的事情的。

      所以,為了項目,為了大家的Work Life Banlance, 我把創(chuàng)建WebApi這件事情減少成了一行代碼。是的,你沒看錯,就是只要一行代碼:

      app.MapMediatorWebAPIs(typeof(CreateCategory).Assembly);

      只要在ASP.Net Minimal API 項目的Progam文件中加入這一行代碼,就可以把指定程序集中所有實現了IRequest<>和INotification的消息類自動生成WebAPI接口。

      看起來很神奇,其實也不神奇。主要就是兩個字:反射。還有泛型。

      簡單來說,就是在指定程序集中,通過反射查找那些類實現了IRequest<>或者INotification,然后在通過對泛型映射WebAPI方法的反射調用,為每個消息類生成WebApi接口。

      Let me show you the code:

      using MediatR;
      using MediatRApplication;
      using Microsoft.AspNetCore.Mvc;
      using Microsoft.Extensions.Configuration;
      using Microsoft.Extensions.Logging;
      using System.Reflection;
      using System.Xml.Linq;
      
      namespace MediatRWebAPI
      {
          public static class MediatorWebAPIExtensions
          {
              /// <summary>
              /// 擴展方法,為所有MediatR Contract 消息類創(chuàng)建WebAPI接口
              /// </summary>
              /// <param name="app"></param>
              /// <param name="assemblies">Contract 消息類所在程序集</param>
              /// <returns></returns>
              public static IEndpointRouteBuilder MapMediatorWebAPIs(this IEndpointRouteBuilder app, params Assembly[] assemblies)
              {
                  //為所有實現了IRequest<>的消息類創(chuàng)建WebAPI接口
                  Type genericRequestType = typeof(IRequest<>);
                  var sendMethodInfo = typeof(MediatorWebAPIExtensions).GetMethod("MapMediatorSendApi", BindingFlags.NonPublic | BindingFlags.Static);
                  foreach (var assembly in assemblies)
                  {
                      //獲取該程序集中所有實現了IRequest<>的消息類類型
                      var requestTypes = assembly.GetTypes().Where(type => !type.IsInterface && type.GetInterfaces().Any(t => t.IsGenericType && t.GetGenericTypeDefinition() == genericRequestType));
                      foreach (var requestType in requestTypes)
                      {
                          //獲取IRequest<>中尖括號中的泛型參數類型。
                          var responseType = requestType.GetInterfaces().First(t => t.IsGenericType && t.GetGenericTypeDefinition() == genericRequestType).GetGenericArguments().First();
                          //反射調用泛型映射WebApi方法
                          var genericMethod = sendMethodInfo.MakeGenericMethod(requestType, responseType);
                          genericMethod.Invoke(null, new object[] { app, requestType.Name });
                      }
      
                  }
                  //為所有實現了INotification的消息類創(chuàng)建WebAAPI接口
                  Type genericNotificationType = typeof(INotification);
                  var publishMethodInfo = typeof(MediatorWebAPIExtensions).GetMethod("MapMediatorPublishApi", BindingFlags.NonPublic | BindingFlags.Static);
                  foreach (var assembly in assemblies)
                  {
                      //獲取該程序集中所有實現了INotification的消息類類型
                      var requestTypes = assembly.GetTypes().Where(type => !type.IsInterface && genericNotificationType.IsAssignableFrom(type));
                      foreach (var requestType in requestTypes)
                      {
                          //反射調用泛型映射WebApi方法
                          var genericMethod = publishMethodInfo.MakeGenericMethod(requestType);
                          genericMethod.Invoke(null, new object[] { app, requestType.Name });
                      }
      
                  }
      
                  return app;
              }
      
      
              /// <summary>
              /// 為實現了IRequest<>的消息類為映射為WebAPI接口,根據消息類名稱生成對應的CRUDD Http Method。
              /// </summary>
              /// <typeparam name="TRequest"></typeparam>
              /// <typeparam name="TResponse"></typeparam>
              /// <param name="app"></param>
              /// <param name="requestTypeName"></param>
              internal static void MapMediatorSendApi<TRequest, TResponse>(IEndpointRouteBuilder app, string requestTypeName) where TRequest : IRequest<TResponse>
              {
                  if (requestTypeName.StartsWith("Create")) //Http Post
                  {
                      var uri = new Uri(requestTypeName.Replace("Create", ""), UriKind.Relative);
                      app.MapPost(uri.ToString(), async ([FromServices] IMediator mediator, [FromBody] TRequest request) =>
                      {
                          TResponse response = await mediator.Send(request);
                          return Results.Created(uri, response);
                      }).WithName(requestTypeName).WithOpenApi();
                  }
                  else if (requestTypeName.StartsWith("Read")) //Http Get
                  {
                      var uri = new Uri(requestTypeName.Replace("Read", ""), UriKind.Relative);
                      app.MapGet(uri.ToString(), async ([FromServices] IMediator mediator, [FromBody] TRequest request) =>
                      {
                          TResponse response = await mediator.Send(request);
                          return Results.Ok(response);
                      }).WithName(requestTypeName).WithOpenApi();
                  }
                  else if (requestTypeName.StartsWith("Update")) //Http Put
                  {
                      var uri = new Uri(requestTypeName.Replace("Update", ""), UriKind.Relative);
                      app.MapPut(uri.ToString(), async ([FromServices] IMediator mediator, [FromBody] TRequest request) =>
                      {
                          TResponse response = await mediator.Send(request);
                          return Results.Ok(response);
                      }).WithName(requestTypeName).WithOpenApi();
                  }
                  else if (requestTypeName.StartsWith("Delete")) //Http Delete
                  {
                      var uri = new Uri(requestTypeName.Replace("Delete", ""), UriKind.Relative);
                      app.MapDelete(uri.ToString(), async ([FromServices] IMediator mediator, [FromBody] TRequest request) =>
                      {
                          TResponse response = await mediator.Send(request);
                          return Results.NoContent();
                      }).WithName(requestTypeName).WithOpenApi();
                  }
                  else  //如不匹配則生成MediatR Send WebAPI接口
                  {
                      app.MapPost("/mediatr/send/" + requestTypeName, async ([FromServices] IMediator mediator, [FromBody] TRequest request) =>
                      {
                          TResponse response = await mediator.Send(request);
                          return Results.Ok(response);
                      }).WithName(requestTypeName).WithOpenApi();
                  }
              }
      
              /// <summary>
              /// 為實現了INotification的消息類映射WebAPI接口。
              /// </summary>
              /// <typeparam name="TNotification"></typeparam>
              /// <param name="app"></param>
              /// <param name="requestTypeName"></param>
              internal static void MapMediatorPublishApi<TNotification>(IEndpointRouteBuilder app, string requestTypeName) where TNotification : INotification
              {
                  app.MapPost("/mediatr/publish/" + requestTypeName, async ([FromServices] IMediator mediator, [FromBody] TNotification notification) =>
                  {
                      await mediator.Publish(notification);
                      return Results.Ok();
                  }).WithName(requestTypeName).WithOpenApi();
              }
          }
      }

      如上就是實現這個功能的所有代碼,為了讓大家看明白,我加了很多注釋。如果哪位小伙伴還不明白就在下面留言。這些代碼最難的地方就是對于泛型接口的處理。

      我的示例項目如下,代碼已經上傳到了GitHub :iamxiaozhuang/MediatRWebAPI (github.com)  大家隨便用。

       

      posted on 2022-11-24 17:10  小莊  閱讀(594)  評論(2)    收藏  舉報

      主站蜘蛛池模板: 国产精品熟女亚洲av麻豆| 天堂影院一区二区三区四区| 国产精品久久久久久久久久久久| 尹人香蕉久久99天天拍| 免费全部高h视频无码| 国产成人99亚洲综合精品| 久久99热只有频精品8| 人妻精品动漫H无码中字| 亚洲国产精品一二三区| 国产亚洲精品AA片在线播放天 | 国产AV影片麻豆精品传媒| 日日噜噜夜夜狠狠视频| 国产成人亚洲日韩欧美| 亚洲成女人图区一区二区| 亚洲国产成人无码影片在线播放| 国产精品中文字幕一区| 黑人大战中国av女叫惨了| 亚洲欧美精品一中文字幕| 日韩中文字幕高清有码| 欧美最猛黑人xxxx| 四虎永久在线精品8848a| 亚洲一区二区三区十八禁| 99久久亚洲精品无码毛片| 东京热高清无码精品| 中文国产不卡一区二区| 海盐县| 天天躁日日躁狠狠躁2018| 人妻系列无码专区69影院| 久久综合亚洲鲁鲁九月天| 国产午夜福利视频一区二区| 高清dvd碟片 生活片| 色老99久久精品偷偷鲁| 国产爆乳无码视频在线观看3| 麻豆国产成人AV在线播放| 亚洲av色香蕉一区二区三区精品| 日韩精品人妻av一区二区三区| 99re6这里有精品热视频| 国产亚洲av人片在线播放| 日韩成人高精品一区二区| 久久久久久久久久久久中文字幕| 视频一区视频二区亚洲视频 |