将终结点图添加到你的ASP.NET Core应用程序中
2021-01-19 08:11
标签:The 理想 dfa middle intro 集成 模式 await 文档 在本文中,我将展示如何使用 作者:依乐祝 原文地址:https://www.cnblogs.com/yilezhu/p/13335749.html 译文地址:https://andrewlock.net/adding-an-endpoint-graph-to-your-aspnetcore-application/ 在本文中,我仅展示如何创建图形的“默认”样式。在我的下一批那文章中,我再创建一个自定义的 ASP.NET Core附带了一个方便的类 此类只有一个方法 现在,我们将创建一个中间件,该中间件使用 这个中间件非常简单-我们使用依赖注入将必要的服务注入到中间件中。将图形写入响应有点复杂:您必须在内存中将响应写到一个 这一切都是必要的,因为 如果 如果图形很小,则可能不会出现此异常,但是如果您尝试映射中等规模的应用程序(例如带有Identity的默认Razor Pages应用程序),则可以看到此异常。 让我们回到正轨上-我们现在有了一个图形生成中间件,所以让我们把它添加到管道中。这里有两个选择: 通常建议使用前一种方法,将终结点添加到ASP.NET Core 3.0应用程序,因此从这里开始。 为了简化终结点注册代码,我将创建一个简单的扩展方法以将 然后,我们可以在 这就是我们要做的。该 我们可以使用 在终结点路由系统中将图形公开为终结点具有如下优点和缺点: 如果最后一点对您来说很重要,那么您可以使用传统的方法来创建终结点,即使用分支中间件。 在您进行终结点路由之前,将分支添加到中间件管道是创建“终结点”的最简单方法之一。它在ASP.NET Core 3.0中仍然可用,它比终结点路由系统要更为,但不能轻松添加授权或高级路由。 要创建中间件分支,请使用 使用此方法的优缺点在本质上与终结点路由版本相反:图形中没有 对我来说,像这样公开应用程序的图形是没有意义的。在下一节中,我将展示如何通过小型集成测试来生成图形。 ASP.NET Core对于运行内存集成测试有很好的设计,它可以在不需要进行网络调用的情况下运行完整的中间件管道和API控制器/Razor页面。 除了可以用来确认应用程序整体正确运行的传统“端到端”集成测试之外,我有时还喜欢编写“健全性检查”测试,以确认应用程序配置正确。您可以使用,在Microsoft.AspNetCore.Mvc.Testing中暴露的底层DI容器中的 现在,让我们来试下吧 现在,我们可以创建一个简单的测试来生成终结点图,并将其写入测试输出。在下面的示例中,我将默认值 除了 测试的大部分内容与中间件相同,但是我们没有编写响应,而是编写了xUnit的 我发现像这样的简单测试通常足以满足我的目的。在我看来有如下这些优点: 不过,也许您想从应用程序中生成此图,但是您不想使用到目前为止显示的任何一种中间件方法将其包括在内。如果是这样,请务必小心在哪里进行。 一般而言,您可以在应用程序中任何使用依赖项注入或有权访问实例的任何位置通过 如果您要尝试在应用程序生命周期的早期生成图形,则必须小心。尤其是 在ASP.NET Core 3.0中,Web基础结构是在通用主机的基础上重建的,这意味着您的服务器(Kestrel)作为一个 在ASP.NET Core 2.x中,将发生以下情况: 而是在ASP.NET Core 3.x上,如下所示: 启动: 需要注意的重要一点是,直到您的 如果您尝试从一个 如果尝试使用其他标准机制来注入早期行为,情况也是如此,如 同样,您不能只是在 这些限制可能不是问题,具体取决于您要实现的目标。对我来说,单元测试方法可以解决我的大多数问题。 无论使用哪种方法,都只能生成本文中显示的“默认”终结点图。这隐藏了很多真正有用的信息,例如哪些节点生成了终结点。在下一篇文章中,我将展示如何创建自定义图形编写器,以便您可以生成自己的图形。 在这篇文章中,我展示了如何使用 我还展示了如何使用简单的集成测试来生成图形数据而无需运行您的应用程序。这避免了公开(可能敏感)的终结点图,同时仍然允许轻松访问数据。 最后,我讨论了何时可以在应用程序的生命周期中生成图形。该 将终结点图添加到你的ASP.NET Core应用程序中 标签:The 理想 dfa middle intro 集成 模式 await 文档 原文地址:https://www.cnblogs.com/yilezhu/p/13335749.htmlDfaGraphWriter
服务在ASP.NET Core 3.0应用程序中可视化你的终结点路由。上面文章我向您演示了如何生成一个有向图(如我上篇文章中所示),可以使用GraphVizOnline将其可视化。最后,我描述了应用程序生命周期中可以检索图形数据的点。
writer
来生成自定义的图如上篇文章所示。使用
DfaGraphWriter
可视化您的终结点DfaGraphWriter
可用于可视化ASP.NET Core 3.x应用程序中的终结点路由:public class DfaGraphWriter
{
public void Write(EndpointDataSource dataSource, TextWriter writer);
}
Write
。EndpointDataSource
包含描述您的应用程序的Endpoint
集合,TextWriter
用于编写DOT语言图(如您在前一篇文章中所见)。DfaGraphWriter
将该图编写为HTTP响应。您可以使用DI 将DfaGraphWriter
和EndpointDataSource
注入到构造函数中:public class GraphEndpointMiddleware
{
// inject required services using DI
private readonly DfaGraphWriter _graphWriter;
private readonly EndpointDataSource _endpointData;
public GraphEndpointMiddleware(
RequestDelegate next,
DfaGraphWriter graphWriter,
EndpointDataSource endpointData)
{
_graphWriter = graphWriter;
_endpointData = endpointData;
}
public async Task Invoke(HttpContext context)
{
// set the response
context.Response.StatusCode = 200;
context.Response.ContentType = "text/plain";
// Write the response into memory
await using (var sw = new StringWriter())
{
// Write the graph
_graphWriter.Write(_endpointData, sw);
var graph = sw.ToString();
// Write the graph to the response
await context.Response.WriteAsync(graph);
}
}
}
StringWriter
,再将其转换为 string
,然后将其写到图形。DfaGraphWriter
写入TextWriter
使用同步 Stream
API调用,如Write
,而不是WriteAsync
。如果有异步方法,理想情况下,我们将能够执行以下操作:// Create a stream writer that wraps the body
await using (var sw = new StreamWriter(context.Response.Body))
{
// write asynchronously to the stream
await _graphWriter.WriteAsync(_endpointData, sw);
}
DfaGraphWriter
使用了异步API,则可以如上所述直接写入Response.Body
,而避免使用in-memory string
。不幸的是,它是同步的,出于性能原因您不应该使用同步调用直接写入Response.Body
。如果您尝试使用上面的模式,则可能会得到如下所示内容的InvalidOperationException
异常,具体取决于所写图形的大小:System.InvalidOperationException: Synchronous operations are disallowed. Call WriteAsync or set AllowSynchronousIO to true instead.
将图形可视化器添加为终结点
GraphEndpointMiddleware
作为终结点添加:public static class GraphEndpointMiddlewareExtensions
{
public static IEndpointConventionBuilder MapGraphVisualisation(
this IEndpointRouteBuilder endpoints, string pattern)
{
var pipeline = endpoints
.CreateApplicationBuilder()
.UseMiddleware
Startup.Configure()
中的UseEndpoints()
方法中调用MapGraphVisualisation("/graph")
将图形终结点添加到我们的ASP.NET Core应用程序中:public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapHealthChecks("/healthz");
endpoints.MapControllers();
// Add the graph endpoint
endpoints.MapGraphVisualisation("/graph");
});
}
DfaGraphWriter
已经在DI中可用,因此不需要额外的配置。导航至http://localhost:5000/graph
将以纯文本形式生成我们的终结点图:digraph DFA {
0 [label="/graph/"]
1 [label="/healthz/"]
2 [label="/api/Values/{...}/ HTTP: GET"]
3 [label="/api/Values/{...}/ HTTP: PUT"]
4 [label="/api/Values/{...}/ HTTP: DELETE"]
5 [label="/api/Values/{...}/ HTTP: *"]
6 -> 2 [label="HTTP: GET"]
6 -> 3 [label="HTTP: PUT"]
6 -> 4 [label="HTTP: DELETE"]
6 -> 5 [label="HTTP: *"]
6 [label="/api/Values/{...}/"]
7 [label="/api/Values/ HTTP: GET"]
8 [label="/api/Values/ HTTP: POST"]
9 [label="/api/Values/ HTTP: *"]
10 -> 6 [label="/*"]
10 -> 7 [label="HTTP: GET"]
10 -> 8 [label="HTTP: POST"]
10 -> 9 [label="HTTP: *"]
10 [label="/api/Values/"]
11 -> 10 [label="/Values"]
11 [label="/api/"]
12 -> 0 [label="/graph"]
12 -> 1 [label="/healthz"]
12 -> 11 [label="/api"]
12 [label="/"]
}
GraphVizOnline
进行可视化显示如下:
将图形可视化工具添加为中间件分支
Map()
命令。例如,您可以使用以下命令添加分支:public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// add the graph endpoint as a branch of the pipeline
app.Map("/graph", branch =>
branch.UseMiddleware
/graph
终结点,您无法轻松地将授权应用于此终结点!从集成测试生成终结点图
WebApplicationFactory
设施实现。这样,您就可以在应用程序的DI上下文中运行代码,而无需通过单元测试。
dotnet new xunit
来运行一个新的xUnit项目(我选择的测试框架)dotnet add package Microsoft.AspNetCore.Mvc.Testing
安装Microsoft.AspNetCore.Mvc.Testing
元素更新为WebApplicationFactory
作为类基础设施;如果您需要自定义工厂,请参阅文档以获取详细信息。WebApplicationFactory
,我还注入了ITestOutputHelper
。您需要使用此类来记录xUnit的测试输出。直接写Console
不会起作用。。public class GenerateGraphTest
: IClassFixture
ITestOutputHelper
以将记录测试的结果输出。在Visual Studio中,您可以通过以下方式查看此输出:打开“测试资源管理器”,导航到GenerateGraph
测试,然后单击“为此结果打开其他输出”,这将以选项卡的形式打开结果:
您无法在
IHostedService
中生成图形IServiceProvider
访问DfaGraphWriter
和EndpointDataSource
服务。这意味着在请求的上下文中(例如从MVC控制器或Razor Page生成)图很容易,并且与您到目前为止所看到的方法相同。IHostedService
。IHostedService
在你的应用程序中运行的。在大多数情况下,这不会产生太大影响,但是与ASP.NET Core 2.x相比,它改变了应用程序的生成顺序。
IHostedService
实现启动。
IHostedService
实现启动。GenericWebHostService
IHostedService
s的执行后中间件管道才会建立。由于UseEndpoints()
尚未被调用,EndpointDataSource
将不包含任何数据!
IHostedService
中的DfaGraphWriter
生成图表,该EndpointDataSource
是空的。IStartupFilter
- Startup.Configure()
执行之前 调用 ,因此EndpointDataSource
将为空。Program.Main
调用IHostBuilder.Build()
来构建一个Host
,然后使用IHost.Services
:来访问服务,直到您调用IHost.Run
,并且服务器已启动,否则您的终结点列表将为空!总结
DfaGraphWriter
和EndpointDataSource
创建应用程序中所有终结点的图形。我展示了如何创建中间件终结点来公开此数据,以及如何将这种中间件与分支中间件策略一起用作终结点路由。EndpointDataSource
未填充,直到后Server
(Kestrel)已经开始,所以你主要限于在请求上下文访问数据。IHostedService
和IStartupFilter
执行得太早以至于无法访问数据,IHostBuilder.Build()
只是构建DI容器,而没有构建中间件管道。