.NET 6.0生成应用程序后无法修改ServiceCollection问题


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();

当我把这个代码写进程序.cs时,我会得到一个类似标题的错误

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

错误消息告诉订单:

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

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllersWithViews();

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

var app = builder.Build();

简短的回答:您根本无法做到这一点,因为这是无效的管道。

tl;dr

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

Program.cs
Startup.cs 

该应用程序的主要入口点是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>();
});
}

如您所见,主方法调用方法-CreateHostBuilder,返回一个IHostBuilder。在这种方法中,我们正在创建一个通用的或换句话说的通用应用程序生成器(与网络应用程序生成器相反,如果在程序.cs内的.net 6中有任何网络应用程序(,它使用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
}
}

这里我们有两种方法——一种用于配置服务,另一种用于将配置添加到我们的appbuilder obj中。返回Main((方法-当我们接收到添加了所有配置的IHostbuilderobj时,我们将执行两个扩展,顺序为-

1) Build()
2) Run()

这就完成了.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();

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

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

app.Run()

(这与我们在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();

了解更多关于中应用程序启动的信息

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

要了解更多关于应用创业公司之间的比较,请单击Me

希望这有帮助,干杯:(

将build((行放在app.run((行的正上方可以解决问题。

因为build((将转换您首先编写的代码。然后它将运行

已经有很多不错的答案了。想分享我的经验。我在这里跟踪tuotial时看到了这个错误。

我的程序.cs在下面

var app = builder.Build();
if (builder.Environment.IsDevelopment())
{
builder.Services.AddDbContext<MvcMovieContext>(options =>
options.UseSqlite(builder.Configuration.GetConnectionString("MvcMovieContext")));
}
else
{
builder.Services.AddDbContext<MvcMovieContext>(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString("ProductionMvcMovieContext")));
}

在更改代码以移动builder.Build()行后,它消失了:

if (builder.Environment.IsDevelopment())
{
builder.Services.AddDbContext<MvcMovieContext>(options =>
options.UseSqlite(builder.Configuration.GetConnectionString("MvcMovieContext")));
}
else
{
builder.Services.AddDbContext<MvcMovieContext>(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString("ProductionMvcMovieContext")));
}
var app = builder.Build();

对我来说,这很有效:写任何建设者。服务。添加。。。之前:建设者Build((;

最新更新