1

I'm using EF-Core in a web-api project, and using the DI mechanism to inject the DBContext to action methods. BUT - In addition - I would like to reach the DB using the EF dbContext, when the server is up, in the startup method - this is a non http context, meaning - the DBContext is not initiated yet - it is initiated in the ConfigureServices method, and it is initiate after the stratup method. For further explanation, this is the Startup.cs and the rest of the relevant flow:

public class Startup { public IConfiguration Configuration {get; } public Startup(IConfiguration configuration) { Configuration = configuration; RepositoriesManager.Initiate(configuration); //In addition - I now would like to use it to initiate repository by using the EF Core dbContext //Another option is to run this methos after adding the dbContext serice - in the ConfigureServices } public void ConfigureServices(IServiceCollection services) { services.Add.... services.AddDbContext<MyDBContext>(options => options.UseSqlServer(Configuration.GetConnectionString("myDB))); //Option to execute it here instead of in the Startup RepositoriesManager.Initiate(configuration); } } 

RepositoriesManager is a static class that using the configuration to get data from external API

public static Class RepositoriesManager { static RepositoriesManager(){} //static constructor public static void Initiate(IConfiguration configuration) { //to make a long story short: GetDataFromDBUsingEF(); } //This method can be called also from action method (controller) - where the myDBContext is passed - this is not the case here public static GetDataFromDBUsingEF(MyDBContext myDBContext = null) { if (myDBContext == null) { //one option - not working: var serviceCollection = new Microsoft.Extensions.DependencyInjection.ServiceCollection(); var sp = serviceCollection.GetService<MyDBContext>(); //second option - also not working: myDBContext = new MyDBContext(); // This should initiate the DBContext in some scenarios } } } 

I'm trying to use the dbContext OnConfiguration method:

protected override void OnConfiguration(DbContextOptionsBuilder optionsBuilder) { if (!optionsBuilder.IsConfigured) { IConfigurationRoot configuration = new ConfigurationBuilder().SetBasePath(AppDomain.CurrentDomain.BaseDirectory).AddJsonFile("appsettings.json").Build(); optionsBuilder.UseSqqlServer(configuration.GetConnectionString("<connection string key>")); } } 

This method should be called in every DbContext initiation using its constructor. Right now it is not being reached when I initiate the dbContext. I assume that the reason is what the documentation claims: "If a model is explicitly set on the options for this context (via Microsoft.EntityFrameworkCore.DbContextOptionsBuilder.UseModel(Microsoft.EntityFrameworkCore.Metadata.IModel)) then this method will not be run".

How can I get the DBContext when its not injected ?

5
  • Where exactly do you need to use the context.? It should really be configured in Startup.ConfigureServices. Commented Jul 4, 2021 at 13:42
  • @Nkosi - I need the context in the Startup method. The ConfigureServices is running afterwards, so it is not yet initiated. In the ConfigureServices I'm using extension method: AddDbContext. Commented Jul 4, 2021 at 13:55
  • 1
    Show the code because I am still not clear about what you are referring to about Startup "method". Commented Jul 4, 2021 at 14:50
  • @Nkosi - I added some more code Commented Jul 5, 2021 at 6:12
  • Inject the db into the Configure method and use it as needed. Read up on how you should be using Startup here learn.microsoft.com/en-us/aspnet/core/fundamentals/startup Commented Jul 5, 2021 at 10:54

1 Answer 1

1

Option 1: Get context in Startup constructor via new

public Startup(IConfiguration configuration) { Configuration = configuration; var contextOptions = new DbContextOptionsBuilder<MvcContext>() .UseSqlServer(Configuration.GetConnectionString("MvcContext")) .Options; using var context = new MvcContext(contextOptions); var configFromDb = context.MvcConfiguration.First(); } 

Option 2: In ConfigureServices call Configure on required options and use context (it will be called when options will be actually used)

public void ConfigureServices(IServiceCollection services) { services.AddControllersWithViews(); services.AddDbContext<MvcContext>(options => { options.UseSqlServer(Configuration.GetConnectionString("MvcContext")); }); services.AddOptions<DbConfigOptions>().Configure<IServiceProvider>((options, sp) => { using var scope = sp.CreateScope(); using var dbContext = scope.ServiceProvider.GetRequiredService<MvcContext>(); options.UseDeveloperExceptionPage = dbContext.MvcConfiguration.Single().UseDeveloperExceptionPage; }); } 

Option 3: When DBContext is configured in ConfigureServices it can be injected in Startup.Configure and used there

public void Configure(IApplicationBuilder app, IWebHostEnvironment env, MvcContext dbContext) { var configFromDb = dbContext.MvcConfiguration.Single(); //... } 
Sign up to request clarification or add additional context in comments.

5 Comments

Thanks - it worked - used option 1 - most suitable for me.
@GuyE option 1 is the least "natural" - you should strive to use option 3
@Aviad P. - I would have if I could, but I need the dbContext to be used in the method which called from the Startup method ( RepositoriesManager.Initiate(configuration);). The Configure method runs after the startUp
Let me know if you want me to have a closer look and suggest a better flow @GuyE
@Aviad P. - Thanks. I'll do if necessary.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.