Reputation: 51
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();
When I Write This Code Into Program.cs I Get An Error Like Title
Upvotes: 5
Views: 23244
Reputation: 21
for me this was working: writing any builder.Services.Add... before: builder.Build();
Upvotes: 2
Reputation: 961
Lot of great answers already. Wanted to share my experience. I saw this error while following the tuotial here.
My Program.cs was like below
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")));
}
After changing the code to move builder.Build()
line, it went away:
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();
Upvotes: 1
Reputation: 438
Putting the build() line just above the app.run() line will fix the problem.
Because build() will convert the code you wrote first. Then it will run
Upvotes: 0
Reputation: 9132
Cannot modify ServiceCollection after application is built
The error message tells the order :
1.Adding services to the service container, there are Add{Service}
extension methods on IServiceCollection. :
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllersWithViews();
2.Then build the WebApplication to return a configured WebApplication.
var app = builder.Build();
Upvotes: 10
Reputation: 127
Short answer : You simply cannot do this , as this is invalid pipeline.
tl;dr
Long answer : Before .net 6 (.net 5,..3.x) we had two files which would handle the total startup flow of the application namely -
Program.cs
Startup.cs
In the main entry point to the application was the Main() method from the Program.cs . Which had content similar to below code -
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>();
});
}
Here as you can see the main method calls method - CreateHostBuilder
which returns an IHostBuilder
. In this method we are creating a generic or in other word general-purpose app builder (as opposed to webapplication builder in case of any web app in .net 6 inside program.cs)- which uses the configurations from the Startup.cs. The Startup.cs content will look like below code -
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
}
}
Here we two methods - one for configuring the service and one for adding configurations to our appbuilder obj.
Back in Main() method - when we receive IHostbuilder
obj with all the configs added to it we are the executing two extensions in the order -
1) Build()
2) Run()
And this completes the startup pipeline in .net 5(or earlier)
In case of .net 6 we are doing more or less same but in a one single file i.e. in 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();
Here on very first line
var builder = WebApplication.CreateBuilder(args);
we are creating a web specific app builder obj in builder
After that as we dont have startup.cs and its configservices method we are doing all required configuration before building the app (remember in case of .net 5/earlier we ran extension method build () after we had IHostbuilder object). And once you had the app object from build() method you want to configure your app object as per your need - same thing we did it in Configure() method in case of .net5/earlier. So you do that by simply applying required extension on app object e.g. app. app.UseRouting();
And a last step of the application startup up pipeline we run the app by calling
app.Run()
(which is same Run() method that we call on IHostBuilder after Buid())
What we can do to keep in mind this pipeline ? - we can form a logical separation in Program.cs like below -
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();
To know more about the app startup in
To know more about the comparison between app startups clickMe
Hope this helps, Cheers :)
Upvotes: 5