【发布时间】:2018-11-05 21:21:40
【问题描述】:
AspNet Core 中是否有一种本机机制,允许将正在完成的工作拆分在一个单一的 Startup 类中,以从长远来看提高可读性/可维护性/可扩展性?如果是这样,它是如何工作的?
我们有一个有点小的 .Net Core MVC WebAPI 项目,它抽象了一些产品目录问题,但在我看来,Startup 类正在快速增长并且变得难以阅读和维护。
以下是一些统计数据:
- 244行代码
- 32 使用命名空间指令
- ~50 行手动域级容器注册
虽然这听起来可能没什么大不了的,但与项目其余部分中遵循 SOLID 原则的一些类相比,这可能令人生畏(尤其是包含的不同命名空间的数量,这很好地表明了 SRP 违规)。
我可以创建一些额外的 .AddX() 扩展方法来减少手动 DI 注册代码的大部分内容(例如,基于“每个模块”或非常类似于 Autofac 的 Registry/Module 或Structuremap) 就像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();
}
}
我可以为上面列出的大多数问题提出类似的小类,由于减少了依赖关系/责任,这将导致整体逻辑大大简化。
我正在寻找无需创建大量自定义基础架构代码来支持它的方法。
【问题讨论】:
-
什么是增长困难?是DI注册吗?这些可以(并且应该)在它们自己的扩展方法中抽象出来。这同样适用于其他一切实际上
-
是的,DI 注册是一个方面,当然会随着 API 本身的功能而增长@Tseng。当您说所有内容都可以类似地重构为扩展方法时,我不太确定我是否跟随您。你如何重构我提到的 MVC/Cors/OData/ApiVersioning/etc 问题?我的意思是,它们本身已经主要是扩展方法。
-
看起来我得到了一些反对意见。如果您能分享原因以便我改进问题,我将不胜感激。
标签: c# asp.net-core startup solid-principles maintainability