When using DB in the Configure method of Startup.cs in ASP.NET Core

1 minute read

Background

I want to refer to the contents of the DB during the process of Configure of Startup.
Specifically, if the DB system setting table is empty at the first startup, I want to forcibly transition to the initial setting screen. For that reason, I wanted to see the DB, but I got stuck a little, so I will write it as a memorandum.
Well, please let me know if anyone is stuck or if there is a better way.

Implementation

When DB is registered as follows in Startup.cs. (Npgsql is cute)

Startup.cs



        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddDbContext<ApplicationDbContext>(options =>
                options.UseNpgsql(
                    Configuration.GetConnectionString("DefaultConnection")));
        ...
        }

Similarly, if you try to use DI in the Configure method of Startup.cs by writing as follows

Startup.cs


        public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ApplicationDbContext dbContext)
        {
            if(dbContext.Settings.Count() == 0)
            {
                //Since the initial setting has not been completed, the initial setting screen is displayed.
                context.Response.Redirect("/Initialize");
                return;
            }
        ...
        }

When I run it, I get the following error message:

ObjectDisposedException: Cannot access a disposed object. A common cause of this error is disposing a context that was resolved from dependency injection and then later trying to use the same context instance elsewhere in your application. This may occur if you are calling Dispose() on the context, or wrapping the context in a using statement. If you are using dependency injection, you should let the dependency injection container take care of disposing context instances.
Object name: ‘ApplicationDbContext’.

There seems to be an object, but it seems that the DB connection inside has been destroyed.
It seems that it is necessary to get it from the argument “IApplicationBuilder app”, but I can not find such an article so I tried it.

Startup.cs


        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            var dbContext = app.ApplicationServices.CreateScope().ServiceProvider.GetRequiredService<ApplicationDbContext>();

            if(dbContext.Settings.Count() == 0)
            {
                //Since the initial setting has not been completed, the initial setting screen is displayed.
                context.Response.Redirect("/Initialize");
                return;
            }
        ...
        }

Then it worked.
What was hard to understand is that app.ApplicationServices also has a “GetRequiredService <>” method, but I can’t get it here. It seems that you have to make a scope as above and get it from the service there.

I hope this is done for the time being, but please comment if there is a way to do this.