89

I created REST API's in .NET 5 and everything was working perfectly, but recently I moved to .NET 6 and realized that no startup.cs class is present. How do I add the DB Context in .NET 6 since there is no startup.cs?

Andrew
  • 18,680
  • 13
  • 103
  • 118
Hernan Garcia
  • 909
  • 1
  • 3
  • 4
  • 1
    Have you seen [Minimal APIs overview](https://learn.microsoft.com/en-us/aspnet/core/fundamentals/minimal-apis?view=aspnetcore-6.0)? Besides, not using the minimal API (and Startup.cs for that matter) equally works in .NET 6 if you have existing code. – Christian.K Feb 02 '22 at 08:12
  • 3
    See also the migration guidance at https://learn.microsoft.com/en-us/aspnet/core/migration/50-to-60?view=aspnetcore-6.0&tabs=visual-studio – jeroenh Feb 02 '22 at 08:13
  • 1
    It is no longer needed. But if you really want to add it back, you may refer to this blog: https://www.strathweb.com/2022/02/using-an-existing-startup-class-with-asp-net-6-minimal-hosting-model/ – Rosdi Kasim Nov 06 '22 at 06:49

6 Answers6

124

In .NET 6 Microsoft has removed the Startup.cs class. Just go to the program.cs file and there you can add a connection string then you've to use builder.Services.AddDbContext The old way is services.AddDbContext

Just use builder.Services and then you can achieve what you want.

Asfend
  • 1,366
  • 1
  • 9
  • 6
  • Oh yeah that's pretty awesome. I've never thought about this that we can call AddDbContext with the builder class. Thanks. – Hernan Garcia Feb 02 '22 at 08:17
  • 4
    You can still use a Startup class if you want. You'll just have to use an older template and upgrade or you can make the previous style Program and Startup classes manually. – juunas Feb 02 '22 at 08:17
  • 2
    the builder resolves by 'var builder = WebApplication.CreateBuilder(args);' which can later be used to configure the DbConetxt , AutoMapper etc.. eg : builder.Services.AddDbContext(opt=>opt.UseInMemoryDatabase("InMem")); After executing the build (var app = builder.Build();) that resolves to IApplicationBuilder Later, that 'app' is used to call the RUN / HTTPRedirection etc.. – jidh Jun 11 '22 at 11:09
  • 1
    @asfend Shouldn't you need to mention that it needs to be written in `Program.cs` file instead? – hiFI Jul 14 '22 at 03:56
47

In .NET 6, they unified Startup.cs and Program.cs into one Program.cs.

Now registering middleware, services and adding DbContext and everything else into the Program.cs file.

Here is an example of a Program.cs file:

using Microsoft.EntityFrameworkCore;

var builder = WebApplication.CreateBuilder(args);
//Register services here
builder.Services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(       
builder.Configuration.GetConnectionString("DefaultConnection")       
));
builder.Services.AddScoped<IUnitOfWork, UnitOfWork>();
//builder.Services.AddAuthentication(...)
var app = builder.Build();
//app.UseAuthentication();

For more information visit this thread.

R15
  • 13,982
  • 14
  • 97
  • 173
14

Create a new class called "Startup.cs". Paste this template in it;

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

    // This method gets called by the runtime. Use this method to add serices to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        //services.AddDbContext...
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(WebApplication app, IWebHostEnvironment env)
    {

    }
}

Now, you can Modify your Program.cs class to look like this;

var builder = WebApplication.CreateBuilder(args);
var startup = new Startup(builder.Configuration); // My custom startup class.

startup.ConfigureServices(builder.Services); // Add services to the container.

var app = builder.Build();

startup.Configure(app, app.Environment); // Configure the HTTP request pipeline.

app.Run();

Now, things are better organized, in the old way. People coming from ASP.NET Core 5 will feel right at home. What you put inside ConfigureServices() and Configure() will depend on your project and needs. For example, here is how an example ASP.NET Core 7 MVC project's Startup.cs would look like as a starting point;

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

    // This method gets called by the runtime. Use this method to add serices to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllersWithViews();
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(WebApplication app, IWebHostEnvironment env)
    {
        if (!env.IsDevelopment())
        {
            app.UseExceptionHandler("/Home/Error");
            // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
            app.UseHsts();
        }

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

        app.UseRouting();

        app.UseAuthorization();

        app.MapControllerRoute(
            name: "default",
            pattern: "{controller=Home}/{action=Index}/{id?}");
    }
}
Emre Bener
  • 681
  • 3
  • 15
6

To be clear for those trying to add transient, singleton or scoped services...

Previously in Startup.cs, adding a service looked like this:

public void ConfigureServices(IServiceCollection services)
{
    services.AddTransient<IEmailService, EmailService>();
}

Now instead in Program.cs, it looks like this:

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddTransient<IEmailService, EmailService>();
Andrew
  • 18,680
  • 13
  • 103
  • 118
  • Should you do this even if your application isn't a "web application" (not an HTTP microservice) but instead a console job that for example... listens to RabbitMQ or processes a file? – Brandon Ros Jan 26 '23 at 16:33
  • @BrandonRos Sure you could find dependency injection useful in a console app, for example, configuration data. Look up "when should you use dependency injection". – Andrew Jan 26 '23 at 17:48
2

I prefer to create an extension class that can be very clean

public static class HostingExtension
{
    /// <summary>
    /// Add services to the container.
    /// </summary>
    /// <param name="builder"></param>
    /// <returns></returns>
    public static WebApplication ConfigureServices(this WebApplicationBuilder builder)
    {

        builder.Services.AddControllers();
        // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
        builder.Services.AddEndpointsApiExplorer();
        builder.Services.AddSwaggerGen();

        return builder.Build();
    }
    /// <summary>
    ///  Configure the HTTP request pipeline.
    /// </summary>
    /// <param name="app"></param>
    /// <returns></returns>
    public static WebApplication ConfigurePipeline(this WebApplication app)
    {
        
        if (app.Environment.IsDevelopment())
        {
            app.UseSwagger();
            app.UseSwaggerUI();
        }

        app.UseHttpsRedirection();

        app.UseAuthorization();

        app.MapControllers();
        return app;
    }
}

and then just write this to program.cs

var builder = WebApplication.CreateBuilder(args);

builder.ConfigureServices().ConfigurePipeline().Run();
A.Bahrami
  • 134
  • 7
1

Go to the program.cs, and then you have to use the builder.Services

Here is an example of a Program.cs file:

var connectionString = builder.Configuration.GetConnectionString("AppDb");
builder.Services.AddDbContext<DbContext>(x => x.UseSqlServer(connectionString));