如何在Startup类中遵循SOLID原则?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在Startup类中遵循SOLID原则?相关的知识,希望对你有一定的参考价值。
在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();
}
}
对于上面列出的大多数问题,我可以提出类似的小类,由于减少了依赖性/责任,这将导致整体逻辑变得非常简单。
我正在寻找实现这一目标的方法,而无需创建大量的自定义基础架构代码来支持它。
我们的启动文件已经增长了很多,但大多数都是在类和辅助方法之后抽象出来的:
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文件。
以上是关于如何在Startup类中遵循SOLID原则?的主要内容,如果未能解决你的问题,请参考以下文章
如何设计遵循 SOLID 的类而不在其他地方加载违反 SOLID 的内容?