Search code examples
c#startupasp.net-core-7.0

How to return IServiceProvider from Startup.ConfigureServices in .NET Core 7


I have a .NET Core 7 web Api application.

That application, by default, has a Program.cs file. However, for some requirement of my application, I need to create a Startup class instead, implementing IStartup interface.

One of the methods I should implement in the Startup class is this: public IServiceProvider ConfigureServices(IServiceCollection services). That method returns an IServiceProvider. This is the implementation I already have:

    public IServiceProvider ConfigureServices(IServiceCollection services)
    {
        services.AddDbContext<SecuWebModulesAuthenticateContext>(options =>
        {
            options
                .UseSqlServer(Configuration.GetConnectionString("DefaultConnection"));
    #if DEBUG
            options.LogTo(Console.WriteLine);
    #endif
        });

        // Agrega autenticación
        services.AddAuthentication()
            .AddCookie("Cookies", options =>
            {
                options.LoginPath = "/Account/Login";
                options.LogoutPath = "/Account/Logout";
                options.AccessDeniedPath = "/Account/AccessDenied";
                options.ReturnUrlParameter = "ReturnUrl";
            })
            .AddJwtBearer(x =>
            {
                x.RequireHttpsMetadata = true;
                x.SaveToken = true;
                x.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuer = true,
                    ValidIssuer = Configuration["AuthJwt:Issuer"],
                    ValidateAudience = true,
                    ValidAudience = Configuration["AuthJwt:Audience"],
                    ValidateIssuerSigningKey = true,
                    RequireExpirationTime = false,
                    ValidateLifetime = true,
                    ClockSkew = TimeSpan.Zero,
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["AuthJwt:Key"] ?? string.Empty))
                };
            });

        services.AddAuthorization();

        return services.BuildServiceProvider();
    }

With that, a warning is shown for the return statement, telling that I will create a new instance of the provider, instead of using the only instance in the system.

How can I do that then?

Thanks Jaime


Solution

  • If you want to use the generic hosting approach (the one supporting Startup classes) then you don't need to implement IStartup interface. If I understand correctly this interface was used quite long ago before ASP.NET Core 3 (for example this question). Nowadays Startup classes rely purely on conventions and the ConfigureServices method should return void. Sample from the docs:

    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }
    
        public IConfiguration Configuration { get; }
    
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddRazorPages();
        }
    
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Error");
                app.UseHsts();
            }
    
            app.UseHttpsRedirection();
            app.UseStaticFiles();
    
            app.UseRouting();
    
            app.UseAuthorization();
    
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapRazorPages();
            });
        }
    }
    

    UPD

    The IStartup interface used in article is a custom one, not the one from framework, so you can/need to declare your own one (I would suggest to use another name to avoid the confusion).