c# - 在 Startup 中合并 aspnetcore 项目,而不复制服务注册或管道

标签 c# asp.net-core

我正在尝试整合我在一个项目中生成的所有垃圾,该项目将我的 Startup 类变成了垃圾场。然而,目前尚不清楚清理和整合是否可以与其他试图做同样事情的图书馆共存。例如,其他库可能需要在 ConfigureServices() 中调用这些:

services.Configure<AuthorizationOptions>(options =>
{
    options.AddSomePolicies();
});
services.AddMvc(options =>
{
    options.Filters.Add(typeof(MyAttribute));
});
services.AddSignalR().AddMyCustomBackplane();

我不太可能拥有唯一需要添加一些身份验证策略、过滤器或激活 SignalR 的库。我无法向自己证明将所有这些包装在 services.MyUltimateExtension() 中不会导致困惑。

同样,我不能轻易地将这些在 Configure() 方法中封装到我自己的库方法中:

app.UseSignalR(routes =>
{
    routes.MapHub<MyHub>("/MyHub");
});
app.UseMvc(routes =>
{
    routes.AddMyRoutes(app);
}

对我来说,这会设置多个 MVC 管道,并且可能会复制 SignalR 基础结构。

我该怎么办?我担心其他开发人员的可读性。

最佳答案

这让我感到疑惑,所以我查看了 UseMvcAddMvc 的工作方式,我可以说多次调用它们是安全的 (< strong>注意事项)。

使用Mvc

UseMvc 做两件事:注册 MVC 服务,并设置所需的 MVC 选项。

注册服务时,它会调用 IServiceCollection.TryAdd方法,它不注册已经注册的服务。这意味着所有 MVC 服务只注册一次。

对于选项,它调用 IServiceCollection.Configure方法。最终选项是通过连续调用每个配置操作来构建的。例如:

调用:

services.Configure<MvcOptions>(options =>
{
    options.EnableEndpointRouting = true;
});

services.Configure<MvcOptions>(options =>
{
    options.EnableEndpointRouting = false;
    options.MaxValidationDepth = 3;
});

相当于:

services.Configure<MvcOptions>(options =>
{
    options.EnableEndpointRouting = true;

    // the last options win
    options.EnableEndpointRouting = false;
    options.MaxValidationDepth = 3;
});

如您所见,调用顺序很重要,因为它可以覆盖一些先前设置的选项。 如果没有重叠是安全的。

AddMvc

AddMvc 做一件事:添加 MVC routing middleware 的新实例每次调用该方法时。

从概念上讲,这意味着调用:

app.UseMvc(routes =>
{
    routes.MapRoute("default", "{controller=Home}/{action=Index}/{id?}");
});

app.UseMvc(routes =>
{
    routes.MapRoute(
        name: "blog",
        template: "Blog/{**article}",
        defaults: new { controller = "Blog", action = "ReadArticle" });
});

相当于调用:

app.UseMvc(routes =>
{
    routes.MapRoute("default", "{controller=Home}/{action=Index}/{id?}");
    routes.MapRoute(
        name: "blog",
        template: "Blog/{**article}",
        defaults: new { controller = "Blog", action = "ReadArticle" });
});

请注意,如果路由之间存在重叠,MVC 框架将拒绝使用 AmbiguousMatchException 的查询。

尝试访问 /Blog/this-is/a/test 会失败:

app.UseMvc(routes =>
{
    routes.MapRoute("default", "{controller=Home}/{action=Index}/{id?}");

    routes.MapRoute(
        name: "blog",
        template: "Blog/{**article}",
        defaults: new { controller = "Blog", action = "ReadArticleOne" });
});

app.UseMvc(routes =>
{
    routes.MapRoute(
        name: "blog",
        template: "Blog/{**article}",
        defaults: new { controller = "Blog", action = "ReadArticleTwo" });
});

那么,你应该怎么做呢?当我的 Startup.cs 变得拥挤时,我所做的是设置一些按意图分组的扩展方法并分成多个类,而不用担心多次调用 UseMvcAddMvc。您唯一需要记住的是调用顺序。

关于c# - 在 Startup 中合并 aspnetcore 项目,而不复制服务注册或管道,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57504377/

相关文章:

c# - 直接插入字节码

c# - 使用 Given-When-Then 模式的 switch-case 测试方法

c# - 如何知道用户在网站上是否仍然在线或离线?

asp.net-core - 具有 Redis 持久性的 MassTransit saga 给出了 Method Accpet does not have an implementation exception

c# - 如何在 vNext Web 应用程序中进行服务器端状态管理

c# - ASP.NET Core Html Helper 使用 TagBuilder 渲染原始文本而不是格式化 HTML

c# - 如何在 Swashbuckle 中显示我的模型中使用的自定义注释?

c# - 在 Excel 工作表/单元格中嵌入文件

c# - 我想用以下方法将 short 转换为 byte

c# - Microsoft ASP.NET 和 Web 工具 2015 - DNX 和 DNVM