.NET 6.0 Cannot modify ServiceCollection after application is built problem

İsa*_*NGİ 5 c# asp.net-core-mvc .net-6.0

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();


app.UseRouting();
builder.Services.AddControllersWithViews();
app.UseEndpoints(endpoints => endpoints.MapControllerRoute(
        name: "default",
        pattern : "{Controller}/{Action}"
    ));
app.Run();

Run Code Online (Sandbox Code Playgroud)

When I Write This Code Into Program.cs I Get An Error Like Title

Qin*_*Guo 10

应用程序构建后无法修改 ServiceCollection

错误消息告诉命令:

1.向服务容器添加服务, IServiceCollection上有Add{Service}扩展方法。:

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllersWithViews();
Run Code Online (Sandbox Code Playgroud)

2.然后构建WebApplication以返回配置的WebApplication。

var app = builder.Build();
Run Code Online (Sandbox Code Playgroud)


小智 4

简短的回答:你根本不能这样做,因为这是无效的管道。

太长了;博士

长答案:在.net 6(.net 5,..3.x)之前,我们有两个文件可以处理应用程序的总启动流程,即 -

Program.cs
Startup.cs 
Run Code Online (Sandbox Code Playgroud)

应用程序的主入口点是 Program.cs 中的 Main() 方法。其中内容类似于以下代码 -

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}
Run Code Online (Sandbox Code Playgroud)

在这里,您可以看到 main 方法调用方法 -CreateHostBuilder它返回一个IHostBuilder. 在这种方法中,我们创建一个通用的或换句话说通用应用程序构建器(与program.cs内的.net 6中的任何Web应用程序的Web应用程序构建器相反) - 它使用Startup.cs中的配置。Startup.cs 内容将类似于以下代码 -

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddRazorPages();

    ...
    ///add configs to the services 
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        app.UseHttpsRedirection();
        app.UseStaticFiles();

        app.UseRouting();

    ...
    ///other configs to app
    }
}
Run Code Online (Sandbox Code Playgroud)

这里有两种方法 - 一种用于配置服务,另一种用于向我们的 appbuilder 对象添加配置。回到 Main() 方法 - 当我们收到添加了所有配置的IHostbuilderobj时,我们正在按顺序执行两个扩展-

1) Build()
2) Run()
Run Code Online (Sandbox Code Playgroud)

这样就完成了.net 5(或更早版本)中的启动管道

对于 .net 6,我们做的事情或多或少相同,但在一个文件中,即Program.cs

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapRazorPages();

app.Run();
Run Code Online (Sandbox Code Playgroud)

在第一行, var builder = WebApplication.CreateBuilder(args); 我们在 builder 中创建一个特定于 Web 的应用程序构建器 obj 之后,由于我们没有startup.cs 及其 configservices 方法,我们在构建应用程序之前进行所有必需的配置(请记住,在 .net 5/之前的情况下,我们在我们拥有 IHostbuilder 对象之后运行扩展方法 build () )。一旦你从 build() 方法中获得了应用程序对象,你就想根据你的需要配置你的应用程序对象 - 在 .net5/早期版本的情况下,我们在 Configure() 方法中做了同样的事情。因此,您只需在应用程序对象上应用所需的扩展即可做到这一点,例如 app.app.UseRouting();

应用程序启动管道的最后一步我们通过调用来运行应用程序

app.Run()
Run Code Online (Sandbox Code Playgroud)

(这与我们在 Buid() 之后在 IHostBuilder 上调用的 Run() 方法相同)

我们可以做些什么来记住这条管道?- 我们可以在 Program.cs 中形成逻辑分离,如下所示 -

var builder = WebApplication.CreateBuilder(args);
{
    // add all the configurations to builder.service obj
    // consider this section as ConfigureServices()
    ...
    builder.Services.AddRazorPages();
    ...

}
var app = builder.Build();
{

    //add configurations to app object 
    //consider this section as Configure()
    ....    
    app.UseRouting();
    app.UseAuthorization();
    app.MapRazorPages();
    ....


}
app.Run();
Run Code Online (Sandbox Code Playgroud)

要了解有关应用程序启动的更多信息

  1. .net 5点击我
  2. .net 6点击我

要了解更多关于应用程序初创公司之间的比较,请点击Me

希望这有帮助,干杯:)