Search code examples
entity-frameworkserviceblazorstartupdbcontext

Blazor WebAssembly DbContext use on startup


I am developing a Blazor WebAssembly and I need to use the DbContext on Startup to write a log entry into database table logs.

On Server Side, I have Program.cs which is setting the services and a Startup.cs which is running some code at startup, like the following:

Program.cs:

var builder = WebApplication.CreateBuilder(args);

var startup = new Startup(builder.Configuration);

// Add services to the container.
builder.Services.AddTransient<Interface_Auth, Service_Auth>();
builder.Services.AddTransient<Interface_Log, Service_Log>();
builder.Services.AddTransient<Interface_User, Service_User>();

//STARTUP SERVICES
startup.ConfigureServices(builder);

var app = builder.Build();

//app.UseResponseCompression();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseWebAssemblyDebugging();
}
else
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseBlazorFrameworkFiles();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.MapRazorPages();
app.MapControllers();
app.MapFallbackToFile("index.html");

//STARTUP APP
startup.Configure(app);

//RUN APP
app.Run();

Startup.cs:

public class Startup
{
    public IConfigurationRoot Configuration { get; }

    public Startup(IConfigurationRoot configuration)
    {
        Configuration = configuration;
    }

    public void ConfigureServices(WebApplicationBuilder builder)
    {
        builder.Services.AddTransient<Interface_Init, Service_Init>();
        builder.Services.AddDbContext<DatabaseContext_Management>(options => options.UseNpgsql(builder.Configuration.GetSection("ConnectionStrings").GetSection("DefaultConnection").Get<string>()), ServiceLifetime.Transient);
        builder.Services.AddSingleton<MyNgpsqlLoggingProvider>();
    
        <AT THIS POINT I NEED TO USE DBCONTEXT>
        _dbContext.........................
    }

Example of context usage on Service:

public class Service_User : Interface_User
{
    readonly DatabaseContext_Management _dbContext = new();

    public Service_User(DatabaseContext_Management dbContext)
    {
        _dbContext = dbContext;
    }

    //To Get all user details   
    public List<User> GetUsers()
    {
        try
        {
            return _dbContext.Users.OrderBy(x => x.user_id).ToList();
        }
        catch
        {
            throw;
        }
    }
}

The service which is connected with an interface is inheriting automatically the DatabaseContext_Management dbContext, but how i can do the same at startup?


Solution

  • You could create a new class that takes the DatabaseContext_Management and writes a log entry:

    public class LogInitializer
    {
        private readonly DatabaseContext_Management _dbContext;
    
        public LogInitializer(DatabaseContext_Management dbContext)
        {
            _dbContext = dbContext;
        }
    
        public async Task WriteLogEntryAsync()
        {
            // Implement your logic to write the log entry to the database
            // Use _dbContext to interact with the database
           
        }
    }
    

    And then register it in ConfigureServices, build a temporary service provider and call your method in the service:

    public void ConfigureServices(WebApplicationBuilder builder)
    {
        builder.Services.AddTransient<Interface_Init, Service_Init>();
        builder.Services.AddDbContext<DatabaseContext_Management>(options => options.UseNpgsql(builder.Configuration.GetSection("ConnectionStrings").GetSection("DefaultConnection").Get<string>()), ServiceLifetime.Transient);
        builder.Services.AddSingleton<MyNgpsqlLoggingProvider>();
    
        // Register LogInitializer
        builder.Services.AddTransient<LogInitializer>();
    
        // Build a temporary service provider to resolve services
        using (var serviceProvider = builder.Services.BuildServiceProvider())
        {
            var logInitializer = serviceProvider.GetRequiredService<LogInitializer>();
            await logInitializer.WriteLogEntryAsync();
        }
    }