如何在Startup类中遵循SOLID原则?

问题描述 投票:1回答:1

在AspNet Core中是否有一个本机机制允许在单片Startup类中拆分工作,以便从长远来看提高可读性/可维护性/可伸缩性?如果是这样,它是如何工作的?

我们有一个小的.Net Core MVC WebAPI项目,它抽象了一些产品目录问题,但Startup类正在快速增长,并且在我看来难以阅读和维护。

以下是一些统计数据:

  • 244行代码
  • 32使用命名空间指令
  • ~50行手动域级容器注册

虽然这可能听起来不是什么大问题,但与项目其余部分遵循SOLID原则的几个类相比,这可能是令人生畏的(特别是包含的不同命名空间的数量是SRP违规的良好指示)。

我可以创建一些额外的.AddX()扩展方法来减少手动DI注册代码的很大一部分(例如,基于“每个模块”的东西或类似于来自Autofac或Structuremap的Registry / Module),如here描述的那样,但是即便如此,我仍会留下一大堆不相关且有些复杂的逻辑来注册/配置像:

  • Mvc(包括自定义过滤器,序列化选项,OData路由,OData EDM模型构建器)
  • Swagger(再次包括自定义和各种设置)
  • ApiVersioning
  • Cors配置
  • 使用外部配置系统的复杂IConfiguration构建器
  • 显式IsDevelopment检查配置默认异常页面

这些看起来都是完全孤立的,独立的问题,我觉得我通过将它们放在同一个类中来违反SRP。

是否有一种已知的机制可以用来将Startup内部的工作分成不同的类,例如更紧密地遵循SRP?这是可取的吗?

即使aspnet核心只支持单个Startup类(我没有发现这方面的确认),我想我可以提出某种复合实现与子Startup类,每个处理这些问题之一,但我不想如果类似的机制已经广泛可用并为此目的而构建,则重新发明轮子或增加复杂性。

这个类如此之大的事实也使得拥有干净的“每个环境”配置变得更加困难,这些配置由会议系统本身支持,因为它可能导致大量的代码重复。

例如,我们在Configure方法中有这个小代码部分:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    // lots of code here

    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
    }

    // ...and lots of code here
}

如果在完全隔离的配置类中抽象出这个逻辑,我们可以改为:

public class ErrorPageConfigurationStartup
{   
    private readonly IApplicationBuilder _app;

    public ErrorPageConfigurationStartup(IApplicationBuilder app)
    {
        _app = app;
    }

    public void Configure()
    {
        app.UseExceptionHandler("/Home/Error");           
    }

    public void ConfigureDevelopment()
    {
        app.UseDeveloperExceptionPage();
    }
}

或者甚至是这个,利用方法级注入:

public class ErrorPageConfigurationStartup
{   
    public void Configure(IApplicationBuilder app)
    {
        app.UseExceptionHandler("/Home/Error");           
    }

    public void ConfigureDevelopment(IApplicationBuilder app)
    {
        app.UseDeveloperExceptionPage();
    }
}

对于上面列出的大多数问题,我可以提出类似的小类,由于减少了依赖性/责任,这将导致整体逻辑变得非常简单。

我正在寻找实现这一目标的方法,而无需创建大量的自定义基础架构代码来支持它。

c# asp.net-core startup solid-principles maintainability
1个回答
1
投票

我们的启动文件已经增长了很多,但大多数都是在类和辅助方法之后抽象出来的:

DI> Startup具有配置方法>转到DI引导程序>转到名为IocConfig.cs的文件,其中包含复合根。交换容器花了几个小时我上次用它作为奖励。

对于.NET Core,配置在内置容器时直接调用,请参阅:https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-2.1

Swagger>当你安装nuget时它应该已经给你一个配置文件,再次在启动时配置1行。

如果在.net Core中不是这种情况,我仍然会手动创建配置文件并移动我的代码。

过去它所做的更多都是相同的,并且与语言无关,创建一个方法或提供者类来抽象出逻辑并让它在启动时触发一两行。

从我所知道的,这里没有标准,你选择去的距离取决于你抽象出代码。例如,我的oauth配置方法是startup.cs底部的方法(它们然后调用更多的类),每个方法大约有十几行,所以将它们移动到自己的类中并没有多大意义,但是缓存singleton有点复杂,所以它得到一个cachingprovider.cs文件。

© www.soinside.com 2019 - 2024. All rights reserved.