5

I working on an ASP.NET Core 2.2 web application. I have some issues when upgrade my application to .NET 6.

My issue is that there's no startup class in .NET 6.0 and I found program.cs file only.

I add startup class on my web application but I don't know how to use it inside Program.cs.

How to add or use startup class inside my program.cs?

This is the startup.cs file in .NET Core 2.2:

public class Startup
{
        private readonly IConfigurationRoot configRoot;
        private AppSettings AppSettings { get; set; }

        public Startup(IConfiguration configuration)
        {
            Log.Logger = new LoggerConfiguration().ReadFrom.Configuration(configuration).CreateLogger();
            Configuration = configuration;

            IConfigurationBuilder builder = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("appsettings.json");
            configRoot = builder.Build();

            AppSettings = new AppSettings();
            Configuration.Bind(AppSettings);
        }

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddController();
            services.AddDbContext(Configuration, configRoot);
            services.AddIdentityService(Configuration);

            services.AddAutoMapper();

            services.AddScopedServices();
            services.AddTransientServices();

            services.AddSwaggerOpenAPI();
            services.AddMailSetting(Configuration);
            services.AddServiceLayer();
            services.AddVersion();

            services.AddHealthCheck(AppSettings, Configuration);
            services.AddFeatureManagement();
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory log)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseCors(options =>
                 options.WithOrigins("http://localhost:3000")
                 .AllowAnyHeader()
                 .AllowAnyMethod());

            app.ConfigureCustomExceptionMiddleware();

            log.AddSerilog();

            //app.ConfigureHealthCheck();

            app.UseRouting();
            app.UseAuthentication();
            app.UseAuthorization();
            app.ConfigureSwagger();

            app.UseHealthChecks("/healthz", new HealthCheckOptions
            {
                Predicate = _ => true,
                ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse,
                ResultStatusCodes =
                {
                    [HealthStatus.Healthy] = StatusCodes.Status200OK,
                    [HealthStatus.Degraded] = StatusCodes.Status500InternalServerError,
                    [HealthStatus.Unhealthy] = StatusCodes.Status503ServiceUnavailable,
                },
            }).UseHealthChecksUI(setup =>
              {
                  setup.ApiPath = "/healthcheck";
                  setup.UIPath = "/healthcheck-ui";
                  //setup.AddCustomStylesheet("Customization/custom.css");
              });

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
}

And this is my .NET 6 program.cs:

var builder = WebApplication.CreateBuilder(args);

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

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/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.MapRazorPages();

app.Run();

How to use the startup class inside program.cs class ?

Updated Post every thing is working but configure service not working because i don't know how to implement ILoggerFactory on startup

 public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory log)
        {
        }

on program.cs

startup.Configure(app, app.Environment,???);

How to add logger factory as third paramter on program.cs ILoggerFactory is buit in class Updated it solved using

var app = builder.Build();
startup.Configure(
    app,
    builder.Environment,
    app.Services.GetRequiredService<FooService>(),
    app.Services.GetRequiredService<ILoggerFactory>()
);

can you please tell me how to apply swagger ui to check my api

Guru Stron
  • 102,774
  • 10
  • 95
  • 132
ahmed barbary
  • 628
  • 6
  • 21
  • See [this migration guide by Microsoft](https://learn.microsoft.com/en-us/aspnet/core/migration/50-to-60?view=aspnetcore-5.0&tabs=visual-studio) which explains how to deal with the changes between earlier .NET Core versions, and .NET 6, when it comes to the startup of your app – marc_s Nov 20 '22 at 09:09
  • i make it but remining call configure function on startup class – ahmed barbary Nov 20 '22 at 09:14
  • Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory log) on startup when calling on program configure give exceptionvar startup = new Startup(builder.Configuration); startup.ConfigureServices(builder.Services); var app = builder.Build(); startup.Configure(app, app.Environment); – ahmed barbary Nov 20 '22 at 09:17
  • This c# corner might help https://www.c-sharpcorner.com/article/how-to-add-startup-cs-class-in-asp-net-core-6-project/ – Zeko Nov 20 '22 at 10:22

2 Answers2

5

You can manually instantiate the Startup and manually call the method ConfigureServices and Configure :

var builder = WebApplication.CreateBuilder(args);

var startup = new Startup(builder.Configuration);
startup.ConfigureServices(builder.Services);

var app = builder.Build();
startup.Configure(app, builder.Environment);

In ASP.NET Core 2.*, Startup.Configure accepted injected service :

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        ...
        services.AddSingleton<IFooService, FooService>();
    }

    public void Configure(WebApplication app, IWebHostEnvironment env, IFooService fooService, ILoggerFactory loggerFactory)
    {

       fooService.Init();
       ...
    }
}

Then you can :

var app = builder.Build();
startup.Configure(
    app,
    builder.Environment,
    app.Services.GetRequiredService<FooService>(),
    app.Services.GetRequiredService<ILoggerFactory>()
);

When I migrated my APIs, first I consider to reuse the Startup class... but finally I moved the configuration in extension methods.

vernou
  • 6,818
  • 5
  • 30
  • 58
4

New templates use the so called minimal hosting model but nobody prevents from switching back to the generic hosting one used previously (or via WebHost).

If you want to work with top-level statements you can copy contents of Main method to the Program.cs file and then copy all other methods declared in the old Program class. New Program.cs potentially can look something like this:

await CreateHostBuilder(args)
    .Build()
    .RunAsync();

// do not forget to copy the rest of the setup if any
static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        });

Or just remove the Startup class completely and move configure methods to corresponding parts of new file (maybe extracting some to concise extension methods).

Guru Stron
  • 102,774
  • 10
  • 95
  • 132