where and how to put custom Function on startup

osyris 236 Reputation points
2021-12-03T21:52:37.867+00:00

I want to create a Admin Seeder that seeds the user and Roles on startup
I have create that function but where do i put it?

In Net 5 i Remember i put my function requirements in the Configure
and than call the function in the Configure section:

example:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env,
            UserManager<ApplicationUser> userManager,
            RoleManager<ApplicationRole> roleManager)

UserAndRoleSeeder.SeedRoles(roleManager);
            UserAndRoleSeeder.SeedUsers(userManager);

I know there is a Override Function on the ApplicationDbContext
but i want that function to start everytime the website starts up not when the database is created

ASP.NET Core
ASP.NET Core
A set of technologies in the .NET Framework for building web applications and XML web services.
4,158 questions
ASP.NET
ASP.NET
A set of technologies in the .NET Framework for building web applications and XML web services.
3,253 questions
0 comments No comments
{count} votes

Accepted answer
  1. AgaveJoe 26,201 Reputation points
    2021-12-04T12:58:06.647+00:00

    The pattern JaliyaUdagedara shared above takes advantage of an extension method. This is a very typically pattern going back to the beginning of Core. Your code is not well designed for Core start up. Plus it expects a role and usermanger service instance.

    I recommend going through any of the getting tutorials in the official documentation as they all cover seeding data. The official documentation also illustrates how to instantiate a service within the seed extension method. Follow the same pattern to get the role and usermanager services.

    Seed the database
    Initialize DB with test data

    This is the pattern I use.

    var builder = WebApplication.CreateBuilder(args);  
      
    // Add services to the container.  
    builder.Services.AddRazorPages();  
      
      
    builder.Services.AddDbContext<RazorPagesMovieContext>(options =>  
           options.UseSqlite(builder.Configuration.GetConnectionString("RazorPagesMovieContext")));  
      
    var app = builder.Build();  
      
    using (var scope = app.Services.CreateScope())  
    {  
        var services = scope.ServiceProvider;  
      
        SeedData.Initialize(services);  
    }  
    

    ....

    public static class SeedData  
    {  
        public static void Initialize(IServiceProvider serviceProvider)  
        {  
            using (var context = new RazorPagesMovieContext(  
                serviceProvider.GetRequiredService<  
                    DbContextOptions<RazorPagesMovieContext>>()))  
            {  
    
    0 comments No comments

4 additional answers

Sort by: Most helpful
  1. Jaliya Udagedara 2,731 Reputation points MVP
    2021-12-04T04:16:14.653+00:00

    I believe you are trying to achieve this for a .NET 6 appication. (since you mentioned .NET 5).

    You can do something like below,

    public static class WebAplicationExtensions
    {
        public static WebApplication SeedData(this WebApplication webApplication)
        {
            IServiceScopeFactory scopedFactory = webApplication.Services.GetRequiredService<IServiceScopeFactory>();
    
            using IServiceScope scope = scopedFactory.CreateScope();
    
            using MyDbContext dbContext = scope.ServiceProvider.GetService<MyDbContext>();
            // TODO: Use dbContext to seed your data
    
            return webApplication;
        }
    }
    

    And in the Program.cs,

    WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
    
    builder.Services.AddDbContext<MyDbContext>(options =>
         options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));
    
    await using WebApplication app = builder.Build();
    
    // Other code
    
    await app
        .SeedData()
        .RunAsync();
    
    0 comments No comments

  2. Bruce (SqlWork.com) 55,601 Reputation points
    2021-12-04T04:19:49.423+00:00

    In program.cs. In the old version it was before defining services, so that would be a good sport, or you could do after defining services. Anywhere you like before app.Run()

    var builder = WebApplication.CreateBuilder(args);
    
    
    // here is where you did it before
    
    // Add services to the container.
    builder.Services.AddRazorPages();
    
    // here is another logical spot
    
    var app = builder.Build();
    
    // Configure the HTTP request pipeline.
    if (!app.Environment.IsDevelopment())
    {
        app.UseExceptionHandler("/Error");
        // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
        app.UseHsts();
    }
    
    app.UseHttpsRedirection();
    app.UseStaticFiles();
    
    app.UseRouting();
    
    app.UseAuthorization();
    
    app.MapRazorPages();
    
    app.Run();
    
    0 comments No comments

  3. osyris 236 Reputation points
    2021-12-04T05:45:18.403+00:00

    Thanks for the replys, but how do I use my Code and put it into that place
    My Admin seeder :

        public class AdminSeeder
        {
            public static void SeedRoles(RoleManager<ApplicationRole> roleManager)
            {
                if (!roleManager.RoleExistsAsync("Admin").Result)
                {
                    var AdminRole = new ApplicationRole();
                    AdminRole.Name = "Admin";
                    AdminRole.Description = "Founder of the company";
    
                    roleManager.CreateAsync(AdminRole).Wait();
                }
    
                if (!roleManager.RoleExistsAsync("Manager").Result)
                {
                    var ManageRole = new ApplicationRole();
                    ManageRole.Name = "Manager";
                    ManageRole.Description = "Leads the employees";
    
                    roleManager.CreateAsync(ManageRole).Wait();
                }
            }
    
            public static void SeedUsers(UserManager<ApplicationUser> userManager)
            {
                if(userManager.FindByEmailAsync("Info@Admin.com").Result == null)
                {
                    var Admin = new ApplicationUser();
                    Admin.Email = "Info@Admin.com";
                    Admin.FirstName = "Johnson";
                    Admin.LastName = "Brown";
                    Admin.UserName = "Admin";
                    Admin.EmailConfirmed = true;
    
                    var result = userManager.CreateAsync(Admin, "Admin_@123").Result;
    
                    if (result.Succeeded)
                        userManager.AddToRoleAsync(Admin, "Admin").Wait();
                }
    
                if (userManager.FindByEmailAsync("Info@Manager.com").Result == null)
                {
                    var Manager = new ApplicationUser();
                    Manager.Email = "Info@Manager.com";
                    Manager.FirstName = "Eric";
                    Manager.LastName = "Smith";
                    Manager.UserName = "Manager";
                    Manager.EmailConfirmed = true;
    
                    var result = userManager.CreateAsync(Manager, "Admin_@123").Result;
    
                    if (result.Succeeded)
                        userManager.AddToRoleAsync(Manager, "Admin").Wait();
                }
            }
    
    
        }
    
    0 comments No comments

  4. osyris 236 Reputation points
    2021-12-04T18:28:16.687+00:00

    Thank you for the helpfull Articles
    I have managed to seed the database:

     public static class SeedAdmin 
        {
            public static async void Initialize(IServiceProvider serviceProvider)
            {
                using (var _dbcontext = new ApplicationDbContext(serviceProvider
                    .GetRequiredService<DbContextOptions<ApplicationDbContext>>()))
                {
    
                    var findAdmin = await _dbcontext.Users.FirstOrDefaultAsync(x => x.Email == "Info@Admin.com");
                    if (findAdmin != null)
                        return;
    
                    var Admin = new ApplicationUser();
                    Admin.Email = "Info@Admin.com";
                    Admin.FirstName = "Johnson";
                    Admin.LastName = "Brown";
                    Admin.UserName = "Admin";
                    Admin.EmailConfirmed = true;
    
                    _dbcontext.Users.Add(Admin);
                    await _dbcontext.SaveChangesAsync();
                }
    
            }
        }
    

    But I would like to implement the UserManager and the RoleManager.
    I have tried serveral ways and i have lookup up other related topics but i could not
    figure out on how to achive this.

    Some help with be well appreciated