【ASP.NET Core】在 Mini-API 中注入服务

asp,net,core,mini,api,注入,服务 · 浏览次数 : 0

小编点评

## Mini API 注入测试代码示例 ```csharp using Microsoft.Extensions.DependencyInjection; using System.Net.Http; public class MyService : IDisposable { public MyService() { Console.WriteLine($\"{nameof(MyService)} 隆重开业\"); } public void Dispose() { Console.WriteLine($"{nameof(MyService)} 即将散伙\"); } public void DoSomething() { Console.WriteLine(\"正忙着呢……别闹\"); } } public class Program { public static void Main(string[] args) { // 使用配置文件 // var builder = WebApplication.CreateBuilder(args); // builder.Services.AddScoped(); // var app = builder.Build(); // 使用 httprepl 工具 var httprepl = new HttpreplClient(); var app = httprepl.GetClient(); app.MapGet("\/", (MyService sv) => { sv.DoSomething(); return "你提交的参数是:123"; }); // 测试单例服务 app.MapGet("/single", () => { var sv = app.Services.GetRequiredService(); sv.DoSomething(); return "我在这里等了你上万年了!"; }); } } ``` **代码说明:** * 代码首先使用 `Microsoft.Extensions.DependencyInjection` 框架注册了一个名为 `MyService` 的服务。 * 使用 `HttpreplClient` 创建了一个 `MyService` 服务实例并绑定了一个回调函数。 * 在回调函数中,我们调用 `DoSomething` 方法,并在方法体内直接引用 `MyService` 的属性或方法。 * 使用 `Httprepl` 的 `Post` 方法模拟 POST 请求,并向服务器发送数据。 * 我们可以通过使用 `app.Services.GetRequiredService` 获取单例服务并调用其方法。 **注意:** * 代码示例仅展示了基本的注入测试,可以根据需求进行扩展。 * 需要安装 `httprepl` 工具才能执行测试。 * 示例代码假设服务器会在应用程序结束时释放服务实例。

正文

经过版本更新,Mini API 的功能逐步完善,早期支持得不太好的 mini API 现在许多特性都可以用了,比如灰常重要的依赖注入。

咱们先来个相当简单的注入测试。来,定义一个服务类,为了偷懒,老周这里就不使用 接口 + 实现类 的方式了。

public class MyService : IDisposable
{
    public MyService()
    {
        Console.WriteLine($"{nameof(MyService)} 隆重开业");
    }

    public void Dispose()
    {
        Console.WriteLine($"{nameof(MyService)} 即将散伙");
    }

    public void DoSomething()
    {
        Console.WriteLine("正忙着呢……别闹");
    }
}

此服务类提供给外部调用的公共方法是 DoSomething。

接下来在容器中注册一下这个服务。

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddScoped<MyService>();
var app = builder.Build();

毕竟,每个 Web API 的调用都是一次消息往返,所以我选择将服务类注册为范围级别的——请求上下文的范围内存活。

最简单好用的注入方式是让服务类的实例通过参数传入。

app.MapGet("/", (MyService sv) =>
{
    // 调用服务类的公共方法
    sv.DoSomething();
    return "三日成精五日成魔七日成鬼";
});

Web API 测试可以不使用第三方工具,dotnet tool 集合有个叫 httprepl 的工具,可以方便使用。此工具需要安装,命令如下:

dotnet tool install -g microsoft.dotnet-httprepl

安装完成后,直接在命令终端输入 httprepl ,回车。就进入了会话模式。假设应用程序的地址是 https://localhost:7249,可以用 connect 命令建立连接。

connect https://localhost:7249

发起请求时,可以用 get、post、put 等命令,对应 HTTP 的请求方式。在上面的例子中,咱们用的是 MapGet 方法注册的 API,相对路径是 /。

get /

调用成功后会返回文本。

而且,MyService 服务也被调用了。

 

接下来咱们改一下代码,添加一个参数x。

app.MapGet("/", (int x, MyService sv) =>
{
    sv.DoSomething();
    return $"你提交的参数是:{x}";
});

在调用 httprepl 工具时,也可以直接将 URL 作为命令行参数传给它,能省去使用 connect 命令。

httprepl https://localhost:7249

然后调用一下 API 。

get /?x=150

得到的响应如下:

 

从上面的改动可以知道:来自依赖注入的参数能够被识别。当然,咱们也可以明确指定各个参数的来源。

app.MapGet("/", ([FromQuery]int x, [FromServices]MyService sv) =>
{
    sv.DoSomething();
    return $"你提交的参数是:{x}";
});

再次运行,再次发出请求。

get /?x=399

 

注入服务在 POST 请求中也可以和作不 body 的参数一起用,例如:

app.MapPost("/send", (Pet p, MyService sv) =>
{
    // 调用服务
    sv.DoSomething();
    string s = string.Format("宠物ID:{0},大名叫{1}", p.ID, p.Name);
    // 返回文本
    return s;
});

参数 sv 是依赖注入自动赋值的,而参数 p 是 Pet 实例,由HTTP请求的 body 部分提供(默认识别 JSON 格式)。Pet 类定义如下:

public class Pet
{
    public int ID { get; set; }
    public string? Name { get; set; }
}

这个类结构很简单,两个成员,用来测试的,不用在意。

在 HttpRepl 工具中可以用 post /send -h content-type=application/json -c ... 的格式提交,-h 指定 HTTP 头,-c 指定 body 部分。但是,在命令行中用 -c 参数指定 body 很难写,而且老容易出错。最好的做法是配置一个文本编辑器。在编辑器中输入好内容,保存关闭文件,然后 httprepl 工具会自动提交。编辑的文件是临时文件,由工具生成,我们不用管它,只要在输入好内容后保存就行。

文本编辑器用啥都行,如记事本。当然,最好设置 VS Code。操作如下:

先进入 httprepl 会话:

httprepl

接着配置 editor.command.default 参数:

pref set editor.command.default "C:\Users\Bug-PC\tools\VSCode\Code.exe"

设置项名称后面是 VS Code 的路径。然后,它会提示你最好加上 -w 参数,于是输入执行:

pref set editor.command.default.arguments "-w"

-w 参数是可以等待 VS Code 响应——等它编辑完关闭后返回 httprepl 工具。

现在,在 httprepl 会话中用 connect 命令连接服务器。

connect https://localhost:7249

发送 POST 请求。

post /send -h content-type=application/json

注意 Content Type 是 JSON 数据。执行后会启动 VS Code,然后我们输入:

{
    "id": 1234,
    "name": "Jack"
}

完成后记得保存文件,并关闭 VS Code。关闭 VS Code 后回到 httprepl 会话,请求自动发送。

 

如果 mini-API 没有定义接收注入的参数,也可以用 HttpContext 来主动请求服务实例。请看下面代码:

app.MapGet("/", (HttpContext context) =>
{
    // 主动请求服务
    MyService sv = context.RequestServices.GetRequiredService<MyService>();
    sv.DoSomething();
    return "我在这里等了你上万年了!";
});

只要在所绑定的委托/方法中提供 HttpContext 类型的参数,就可以自动注入。随后在方法体中就可以直接引用。

这里要注意:此处咱们不能用 app.Services 去请求服务,因为它引用的是根容器(应用程序最开始创建的),不能访问生生命周期为 Scoped 的服务。

我们尝试把服务注册为单实例,看能不能用 app.Services 来获取。

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSingleton<MyService>();
var app = builder.Build();

app.MapGet("/", () =>
{
    // 主动请求服务
    MyService sv = app.Services.GetRequiredService<MyService>();
    sv.DoSomething();
    
    return "我在这里等了你上万年了!";
});

运行程序后,在 httprepl 中用 get / 命令测试通过。这说明,单例服务是支持通过 app.Services 获取的。不过,MyService 实例要等到应用程序结束时才会释放。

 

与【ASP.NET Core】在 Mini-API 中注入服务相似的内容:

【ASP.NET Core】在 Mini-API 中注入服务

经过版本更新,Mini API 的功能逐步完善,早期支持得不太好的 mini API 现在许多特性都可以用了,比如灰常重要的依赖注入。 咱们先来个相当简单的注入测试。来,定义一个服务类,为了偷懒,老周这里就不使用 接口 + 实现类 的方式了。 public class MyService : IDi

【ASP.NET Core】动态映射MVC路由

ASP.NET Core 中的几大功能模块(Razor Pages、MVC、SignalR/Blazor、Mini-API 等等)都以终结点(End Point)的方式公开。在HTTP管道上调用时,其扩展方法基本是以 Map 开头,如 MapControllers、MapBlazorHub。 对于

如何在现有项目中使用`Masa MiniApi`?

首先我们现有创建一个空的WebApi的项目模板,这个项目模板和MasaFramework本身没有任何关联,我们本博客只是使用的MasaFramework的MiniApi的包 创建Asp.NET Core 空的项目模板 项目名称MFMiniApi 其他信息看图,取消Https配置,也可以选择, 这就是

【ASP.NET Core】在node.js上托管Blazor WebAssembly应用

由于 Blazor-WebAssembly 是在浏览器中运行的,通常不需要执行服务器代码,只要有个“窝”能托管并提供相关文件的下载即可。所以,当你有一个现成的 Blazor wasm 项目,没必要用其他语言重写,或者你不想用 ASP.NET Core 来托管(有些大材小用了),就可以试试用 node

.NET 8 Release Candidate 1 (RC1)现已发布,包括许多针对ASP.NET Core的重要改进!

这是我们计划在今年晚些时候发布的最终.NET 8版本之前的两个候选版本中的第一个。大部分计划中的功能和变更都包含在这个候选版本中,可以供您尝试使用。您可以在文档中找到完整的ASP.NET Core在.NET 8中的新功能列表。一些领域(尤其是Blazor)仍然有一些重大的变更待完成,我们预计将在下一

NET9 AspnetCore将整合OpenAPI的文档生成功能而无需三方库

OpenAPI 规范是用于描述 HTTP API 的标准。该标准允许开发人员定义 API 的形状,这些 API 可以插入到客户端生成器、服务器生成器、测试工具、文档等中。尽管该标准具有普遍性和普遍性,但 ASP.NET Core 在框架内默认不提供对 OpenAPI 的支持。 当前 ASP.NET

【源码解读】asp.net core源码启动流程精细解读

引言 core出来至今,已经7年了,我接触也已经4年了,从开始的2.1,2.2,3.1,5,6再到如今的7,一直都有再用,虽然我是一个Winform仔,但是源码一直从3.1到7都有再看,然后在QQ上面也一直比较活跃,之前好几年前一直说给大家解读asp.net core源码,在之前的博客中,讲的都是比

Asp-Net-Core开发笔记:使用RateLimit中间件实现接口限流

前言 最近一直在忙(2月份沉迷steam,3月开始工作各种忙),好久没更新博客了,不过也积累了一些,忙里偷闲记录一下。 这个需求是这样的,我之前做了个工单系统,现在要对登录、注册、发起工单这些功能做限流,不能让用户请求太频繁。 从 .Net7 开始,已经有内置的限流功能了,但目前我们的项目还在使用

Asp-Net-Core学习笔记:gRPC快速入门

## 前言 此前,我在做跨语言调用时,用的是 Facebook 的 Thrift,挺轻量的,还不错。 >Thrift是一种接口描述语言和二进制通讯协议,它被用来定义和创建跨语言的服务。它被当作一个远程过程调用(RPC)框架来使用,是由Facebook为“大规模跨语言服务开发”而开发的。它通过一个代码

【ASP.NET Core】MVC操作方法如何绑定Stream类型的参数

咱们都知道,MVC在输入/输出中都需要模型绑定。因为HTTP请求发送的都是文本,为了使其能变成各种.NET 类型,于是在填充参数值之前需 ModelBinder 的参与,以将文本转换为 .NET 类型。 尽管 ASP.NET Core 已内置基础类型和复杂类型的各种 Binder,但有些数据还是不能