MinimalApis自动注册

前言

Asp.Net Core 6 推出了最小 Api(MinimalApis)来简化WebApi的开发,在前后端分离的趋势下越来越多的后端服务只提供Api接口,但是用Controller的开发模式会引入MVC的架构,MinimalApis的出现就是来减少框架的依赖,让 Api 的开发更加简洁,并且可以优化性能。

本文的重点是解决MinimalApis的使用痛点,让大家如何优雅的使用MinimalApis,教程大家可以浏览官网。

MinimalApis教程一览

本文的完整源代码在末尾

创建 MinimalApis 的项目

VS 创建新项目->输入项目名字然后点击下一步-> 使用控制器的 CheckBox 确定取消勾选

当然还有其他的方式比如 命令行dotnet new web 或者是使用 vs 创建一个Asp.Net Core 空的模板,自己添加 MinimalApi 的配置等

当我们创建完项目后大概的结构是这样的

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.MapGet("/sayHello", (string name) =>
{
    return $"hello {name}";
}).WithName("sayHello")
.WithOpenApi();
app.Run();

原模板中是获取天气的接口,我简单改了一下让看起来更简单。

endPoint是通过app.MapGet,app.MapPost,app.MapPut,app.MapDelete等一系列IEndpointRouteBuilder的扩展方法注册到应用程序中去的,设想一下一个项目到几十个,几百个接口的程度那我们的系统将难以维护。

当然也可以把扩展方法写到几个扩展方法中然后在 Program 中引入,比如app.UseUserApi,app.UseRoleApi在业务接口扩展的时候不停的手动加这些扩展方法也不够优雅。

下面提供一种自动注册的方案

自动注册MinimalApis

自动注册 MinimalApis 不仅仅是为了简化我们注册的流程,更重要的是为了符合业务的垂直结构,为了业务更好的进行业务规划,参考 Controller 的开发流程,通过建立标准的注册机制,让我们的代码维护性更高。

第一步创建 IEndPoint 的接口

让我们来定义一个接口来表示我们一个或者是一组路由的终结点(endPoint)

public interface IEndPoint
{
    void MapEndPoints(IEndpointRouteBuilder app);
}

创建EndPoints文件夹

为什么要创建这个文件夹呢,可以理解和 Controllers 文件夹约定一样,我们所有的 IEndPoint 的实现都在这里,每一个 IEndPoint 的实现都处理一组相关的业务。
设想的结构是这样的

project-name
│
├── EndPoints
│   ├── TodoEndPoints.cs
│   └── UserEndPoints.cs

接下来我们实现一个相关业务的 EndPoints

public class TodoEndPoints : IEndPoint
{
    public void MapEndPoints(IEndpointRouteBuilder app)
    {
        var group = app.MapGroup("Todo");//EndPoint 前缀
        group.WithTags("Todo");//OpenApi Swagger 分组
        group.MapGet("/", () => "Get").WithSummary("Get 接口");
        group.MapPost("/", () => "Post").WithSummary("Post 接口");
        group.MapDelete("/", () => "Get").WithSummary("Delete 接口");
        group.MapPut("/", () => "Put").WithSummary("Put 接口");
    }
}

反射注册

Program.cs 的中通过反射获取所有的 IEndPoint 的实现来批量注册注册到我们的路由中。
实现如下

public static class EndPointsExtensions
{
    public static WebApplication RegisterEndPoints(this WebApplication app)
    {
        var types = Assembly.GetEntryAssembly()?.GetTypes()?.Where(type => type.IsAssignableTo(typeof(IEndPoint)) && type is { IsAbstract: false, IsInterface: false });
        if (types?.Count() > 0)
        {
            foreach (var type in types)
            {
                var ep = ActivatorUtilities.CreateInstance(app.Services, type);
                (ep as IEndPoint)!.MapEndPoints(app);

            }
        }
        return app;
    }
}

定义了一个WebApplication的扩展来注册我们的endPoints,所有被注册的实现必须要非抽象的并且不是接口还要继承IEndPoint

program.cs 添加注册

var app = builder.Build();

app.RegisterEndPoints();//路由终结点自动注册

在 app 下执行我们的RegisterEndPoints扩展方法,此时所有符合条件的路由终结点将被注册到应用程序中。

测试

项目直接Run
Swagger 自动打开调用一下接口测试即可

测试效果图

可以看到我们所有的路由终结点都成功被注册到了应用程序中 🥰。

最后

实现这个需求其实很简单,重要的是怎么在项目中结合业务来实现一个垂直切分的架构,让 MinimalApis 不再分散,业务模块化管理,架构更容易维护才是我们要实现的目标。

以下是本文的完整 源代码

希望本文对大家有所帮助!!!

posted @ 2024-03-12 11:02  董瑞鹏  阅读(70)  评论(0编辑  收藏  举报