5

Is there a way to access the DB context of a .NET Core application in the program.cs file? I am basically looking to configure Kestrel with specific options that are stored in the database so I would need access to the database context.

I am basically trying to do something like this:

WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>()
            .UseSentry()
            .UseKestrel(opts =>
                 {
                    opts.Listen(IPAddress.Any, 443, listenOptions =>
                    {
                        var storedCert = _db.Certificates.First(c => c.Id == 1);
                        var certBytes = Convert.FromBase64String(storedCert.CertificatePfx);
                        var certPassword = storedCert.CertificatePassword;

                        var cert = new X509Certificate2(certBytes, certPassword);

                        listenOptions.UseHttps(cert);
                    });
                });
Tachyon
  • 2,171
  • 3
  • 22
  • 46

7 Answers7

2

Try to do the following:

var host = CreateWebHostBuilder(args).Build();

var scope = host.Services.CreateScope();

var ctx = scope.ServiceProvider.GetRequiredService<MyDbContext>();       

//get a new WebHostBuilder
CreateWebHostBuilder(args)
//Configure here using the ctx
.Build()
.Run();
Anton Toshik
  • 2,621
  • 2
  • 19
  • 42
2

The trick is about how to create a scoped service within a singleton :


    public static void Main(string[] args)
    {
        CreateWebHostBuilder(args).Build().Run();
    }

   public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>()
            .UseKestrel(opt => {
                var sp = opt.ApplicationServices;
                using(var scope = sp.CreateScope() ){
                    var dbContext=scope.ServiceProvider.GetService<AppDbContext>();
                    var e= dbContext.Certificates.FirstOrDefault();
                    // now you get the certificates
                }
            });
    }
itminus
  • 23,772
  • 2
  • 53
  • 88
1

Well the below code worked for me for .net 6

using (var scope = app.Services.CreateScope())
{
    var service = scope.ServiceProvider;
    var context = service.GetService<MyAppDbContext>();
}

Using this you can use not only get dbcontext but any other service. Consider below example for usermanager object of identity class:

var userManager = services.GetRequiredService<UserManager<ApplicationUser>>();
raw_hitt
  • 719
  • 5
  • 21
0

I figured out how to go about doing this. You need to manually build up the configuration for the DB context then instantiate the context, then you are able to use it. Here is the code in case anyone is in this position.

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>()
                .UseSentry()
                .UseKestrel(opts =>
                {
                    opts.Listen(IPAddress.Any, 443, listenOpts =>
                    {
                        //Create the configuration to read from appsettings.json
                        var configuration = new ConfigurationBuilder().AddJsonFile(
                                Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "appsettings.json"))
                            .Build();

                        //Create the DB Context options
                        var optionsBuilder = new DbContextOptionsBuilder<DBContext>()
                            .UseSqlServer(configuration["ConnectionString:Development"]);

                        //Create a new database context
                        var context = new DBContext(optionsBuilder.Options);

                        //Get the certificate
                        var certificate = context.Certificates.First();
                    });
                });
Tachyon
  • 2,171
  • 3
  • 22
  • 46
  • That's not a good way. You're building the configuration twice. Also there's no need to create the DbContext manually . The only trick is to create a scoped service within a singleton : `.UseKestrel(opt => { var sp = opt.ApplicationServices; using(var scope = sp.CreateScope() ){ var dbContext=scope.ServiceProvider.GetService(); var c= dbContext.Certificates.First(); } });` – itminus Mar 07 '19 at 09:56
  • @itminus - That works perfectly - thank you so much. If you'd like to post it as an answer I will mark it as accepted :) – Tachyon Mar 07 '19 at 10:04
  • 1
    Thanks very much. Done :) – itminus Mar 07 '19 at 10:09
-1

Yes you can get service using following code

 var host = BuildWebHost(args);

DbContext context = host.Services.GetService<DbContext>();

and code to register your DbContext in startup.cs is as follows

services.AddDbContext<DbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
Ikram Shah
  • 1,206
  • 1
  • 11
  • 12
  • I need to use the context within the configuration of `CreateDefaultBuilder` so this will not work. – Tachyon Mar 07 '19 at 09:11
-1

For build deb context and program.cs:

builder.Services.AddDbContext<StudentDbContext>(option =>
    option.UseSqlServer(builder.Configuration.GetConnectionString("DBCS")));
Jeremy Caney
  • 7,102
  • 69
  • 48
  • 77
  • add ctor in db context - public StudentDbContext(DbContextOptions options) : base(options) { } public DbSet Students { get; set; } } } – Sunil Singh Dec 04 '22 at 07:01
  • Connection strings - "ConnectionStrings": { "DB": "Server=DESKTOP-EN9GE2A\\SQLEXPRESS; Database=StudentRegDB; Trusted_Connection=True;" } } – Sunil Singh Dec 04 '22 at 07:02
  • access db context -builder.Services.AddDbContext(options => options.UseSqlServer(builder.Configuration.GetConnectionString("DB"))); – Sunil Singh Dec 05 '22 at 04:08
-2

[1] Connection String -
a) "ConnectionStrings": { "DB": "Server=SQL Server Name; Database=Name Of Database; Trusted_Connection=True;Trust Server Certificate=true" }

  • [2] Add DbContext - public StudentDbContext(DbContextOptions options) : base(options) { } public DbSet Students { get; set; } } [3] builder.Services.AddDbContext(options => options.UseSqlServer(builder.Configuration.GetConnectionString("DB"))); – Sunil Singh Dec 05 '22 at 17:08