AspNet Core中是否有一种本地机制,允许在单片Startup
类中拆分正在完成的工作,从而从长远来看提高可读性/可维护性/可扩展性?如果是,它是如何工作的?
我们有一个有点小的.Net Core MVC WebAPI项目,它抽象了一些产品目录问题,但在我看来,Startup
类增长很快,很难阅读和维护。
以下是一些统计数据:
- 244行代码
- 32使用命名空间指令
- 约50行手动域级容器注册
虽然这听起来可能没什么大不了的,但与项目其余部分中遵循SOLID原则的少数类相比,这可能会让人望而却步(尤其是包含的不同名称空间的数量,这很好地表明了违反SRP(。
我可以创建一些额外的.AddX()
扩展方法来减少手动DI注册代码的很大一部分(例如,基于"每个模块"或与Autofac或Structuremap的Registry
/Module
非常相似的东西(,就像这里描述的那样,但即使这样,我也会留下大量不相关且有点复杂的逻辑来注册/配置东西,比如:
- 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 has configure method>转到DI引导程序>转到包含复合根的名为IocConfig.cs的文件。上一次我交换集装箱花了几个小时,作为奖励。
对于.NET Core,配置是在容器内置时直接调用的,请参阅:https://learn.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-2.1
Swagger>当你安装nuget时,它应该已经给了你一个配置文件,在启动时再加一行配置。
如果.net Core中不是这种情况,我仍然会手动创建配置文件并移动代码。
过去,它都在做更多相同的事情,并且与语言无关,制作一个方法或提供程序类来抽象出逻辑,并在启动时启动一两行。
根据我的判断,这里没有标准,你选择走多远取决于你对代码的抽象。例如,我的oauth-configure方法是startup.cs底部的方法(然后它们调用更多的类(,每个方法大约有十几行,所以将它们移到自己的类中没有多大意义,但是缓存singleton有点复杂,所以它会得到一个cachingprovider.cs文件。