我正在try 自动实现我的应用程序的CRUD.

我使用的是最小的API设计,我写了一个ICrudService<T>,它可以是GetSingleAddUpdateDeleteT实体.

现在,我正在try 将端点部分自动化.我可以让GetSingle使用这个代码:

Type[] types = 
{ 
    typeof(Place), 
    typeof(PlaceLink),
};

foreach (var type in types)
{
    var scope = app.Services.CreateScope();
    var serviceType = typeof(ICrudService<>).MakeGenericType(type);
    dynamic service = scope.ServiceProvider.GetService(serviceType);

    app
    .MapGet($"/{type.Name.ToLower()}s", async () =>
    {
        var result = await service.Get();
        return Results.Ok(result);
    })
    .WithTags($"{type.Name}s");

    app
    .MapGet($"/{type.Name.ToLower()}s/" + "{id}", async (int id) =>
    {
        var result = await service.Single(id);
        return Results.Ok(result);
    })
    .WithTags($"{type.Name}s");
}

这给了我想要的昂首阔步:

enter image description here

但我正在努力应对Add的挑战(可能还有Update的挑战).

以下是Add部分的实际代码:

app
.MapPost($"/{type.Name.ToLower()}s/" + "{id}", async(TYPE_OF_ENTITY entity) =>
{
    var result = await service.Add(entity);
    return Results.Ok(result);
})
.WithTags($"{type.Name}s");

我可以通过使用.MakeGenericType(type)函数得到service.但在这里,async(TYPE_OF_ENTITY entity)是一个匿名函数的签名,我不知道是否有什么技巧可以用来通过使用type变量来指定entity变量中的Type.

关键字dynamic可以工作,但Swagger无法知道My Entity的类型,因此图形用户界面显示为RAW,没有任何请求的默认模式:

如何动态创建匿名函数的签名?

enter image description here

推荐答案

要执行动态最小API注册,可以将设置移到泛型方法中,然后通过反射调用它.例如:

class MapExts
{
    public static void MapType<T>(WebApplication app)
    {
        Type type = typeof(T);
        app
            .MapGet($"/{type.Name.ToLower()}s", async (ICrudService<T> service) =>
            {
                var result = await service.Get();
                return Results.Ok(result);
            })
            .WithTags($"{type.Name}s");

        app
            .MapGet($"/{type.Name.ToLower()}s/" + "{id}", async (int id, ICrudService<T> service) =>
            {
                var result = await service.Single(id);
                return Results.Ok(result);
            })
            .WithTags($"{type.Name}s");

        app
            .MapPost($"/{type.Name.ToLower()}s/" + "{id}", async (T entity, ICrudService<T> service) =>
            {
                var result = await service.Add(entity);
                return Results.Ok(result);
            })
            .WithTags($"{type.Name}s");
    } 
}

和用法:

var mapMethod = typeof(MapExts).GetMethod(nameof(MapExts.MapType));
foreach (var type in types)
{
    mapMethod.MakeGenericMethod(type).Invoke(null, new object?[] { app });
}

附注:

这一点:

var scope = app.Services.CreateScope();
var serviceType = typeof(ICrudService<>).MakeGenericType(type);
dynamic service = scope.ServiceProvider.GetService(serviceType);

是很糟糕的.这不仅是因为使用dynamic类型(这可能是自以为是的说法),而且这将导致相同的服务实例在应用程序生命周期内处理所有请求,这可能会导致许多不同的问题,具体取决于实际的服务实现.

Csharp相关问答推荐

ASP.NET Core -如何解决Fluent验证中无法访问的扩展方法Message Formatter错误

如何将两个查询结果组合在C#ASP.NET MHC控制器中

发布.NET框架项目将.NET核心元素注入到web. connect中

当Visual Studio处于升级管理模式时,无法安装Torch运行时

ASP.NET Core -是否可以对所有最小API端点应用过滤器?

如何创建ASP.NET Core主机并在同一进程中运行请求

C#自定义字典与JSON(de—)serialize

如何保持主摄像头视角保持一致?

使用LayoutKind在C#中嵌套 struct .显式

ASP.NET Core 8.0 JWT验证问题:尽管令牌有效,但SecurityTokenNoExpirationError异常

碰撞检测与盒碰撞器,其isTrigger on问题

C#方法从AJAX调用接收NULL

WeakReference未被垃圾收集

如何在C#中创建VS代码中的控制台应用程序时自动生成Main方法

如何将端点(或с匹配请求并判断其路径)添加到BCL?

MSI无法将快捷方式添加到启动文件夹

基于C#方法的EF核心过滤查询(缓冲与流)

用于请求用户返回列表的C#Google API

Visual Studio,Docker容器-容器调用:连接被拒绝

使用可空引用类型时C#接口实现错误