0

I'm trying to make user identity seeding in OnModelCreating.

First: ApplicationDbInitializer is the class dedicated to seed a user using UserManager and looks like this:

public class ApplicationDbInitializer
{
    public UserManager<AppUser> userManager { get; set; }

    public ApplicationDbInitializer(UserManager<AppUser> _userManager)
    {
        userManager = _userManager;
    }

    public void SeedUsers()
    {
        string Email = Environment.GetEnvironmentVariable("Email");

        if (userManager.FindByEmailAsync(Email).Result == null)
        {
            AppUser user = new AppUser
            {
                Id = SeedingIDs.ManagerID,
                Name = Environment.GetEnvironmentVariable("Name"),

                UserName = "test",
                NormalizedUserName = "test".ToUpper(),

                PhoneNumber = Environment.GetEnvironmentVariable("Phone"),
                PhoneNumberConfirmed = true,

                Email = Email,
                NormalizedEmail = Email.ToUpper(),
                EmailConfirmed = true,

                Bio = "...",
                Pic = "/assets/img/Me.jpg",
                Title = "Full-Stack Web Developer",
                IsManager = true,
                PasswordHash = "test@123",
            };

            IdentityResult result = userManager.CreateAsync(user, "adrg*&$IUHB475").Result;

            if (result.Succeeded)
            {
                userManager.AddToRoleAsync(user, "Admin").Wait();
            }
        }
    }
}

OnModelCreating

    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);

        builder.ApplyConfiguration(new SeedingRoles());
            //builder.Entity<AppUser>().HasData(Initialize);

        ApplicationDbInitializer.SeedUsers();

        builder.Entity<IdentityUserRole<string>>().HasData(new IdentityUserRole<string>
        {
            RoleId = SeedingIDs.RoleID,
            UserId = SeedingIDs.ManagerID
        });

        builder.ApplyConfiguration(new SeedingCategories())
            .ApplyConfiguration(new SeedingBootstrapCategory())
            .ApplyConfiguration(new SeedingTopics())
            .ApplyConfiguration(new SeedingBootstrapTool())
            .ApplyConfiguration(new SeedingPosts());

    }

The problem: I get this error as shown here

enter image description here

It's not a problem if the ApplicationDbInitializer class is static or non-static but I need to include it into OnModelCreating.

Progman
  • 16,827
  • 6
  • 33
  • 48
MOHAMED ABUELATTA
  • 305
  • 2
  • 5
  • 15
  • You need to create an instance of `ApplicationDbInitializer` first, but where do you get the `UserManager` instance from? – Progman Jul 03 '21 at 21:21
  • Have you tried to add it to the DI Container as a singleton and inject it in the constructor of the `ApplicationDbContext`? – Ali Jul 03 '21 at 21:49
  • @Progman I got UserManager instance from the constructor of ApplicationDbInitializer. – MOHAMED ABUELATTA Jul 03 '21 at 22:07
  • @Ali I tried to do that but it gives me another error Unable to create an object of type 'ApplicationDbContext'. For the different patterns supported at design time – MOHAMED ABUELATTA Jul 03 '21 at 22:18
  • Does this answer your question? [How do I call a non-static method from a static method in C#?](https://stackoverflow.com/questions/1360183/how-do-i-call-a-non-static-method-from-a-static-method-in-c) – Progman Jul 03 '21 at 22:19
  • @Progman but you know, with a little of debugging I found it returns null I mean UserManager, although I made injection !! don't know why – MOHAMED ABUELATTA Jul 03 '21 at 22:35
  • @MOHAMEDABUELATTA It shouldn't be `null`. How have you created the `ApplicationDbInitializer` instance? And where do you configure/create the `UserManager` instance? – Progman Jul 03 '21 at 22:43

1 Answers1

0

Thanks for you all guys Progman and Ali. I found another solution.

I'm not sure but It seems using UserManager inside OnModelCreating not preferred.

Anyway, I used instead ModelBuilder to initiate user identity data.

First: I made a Static class that contains user data as follows.

public static class Initialize
{
    public static AppUser Manager(string UserName, string Password)
    {
        string Email = "your email here";
        string Name = "your name";
        string PhoneNumber = "your phone";

        AppUser AdminUser = new AppUser {

            Id = Guid.NewGuid(),
            Name = Name,

            UserName = UserName,
            NormalizedUserName = UserName.ToUpper(),

            PhoneNumber = PhoneNumber,
            PhoneNumberConfirmed = true,

            Email = Email,
            NormalizedEmail = Email.ToUpper(),
            EmailConfirmed = true,

            Bio = "...",
            Pic = "/assets/img/Me.jpg",
            Title = "...",
            IsManager = true,
            PasswordHash = Password
        };
        //PasswordHasher<AppUser> ph = new PasswordHasher<AppUser>();
        //AdminUser.PasswordHash = ph.HashPassword(AdminUser, Password);
        return AdminUser;
    }

}

Note: for some reason, I found using environment to get variables like the following, is working just on run time but returning null when executing add-migration.

string Email = Environment.GetEnvironmentVariable("MyEmail");

Next: I use ModelBuilder in OnModelCreating to seed that user by calling Initialize class as follows

    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);

        builder.Entity<AppUser>().HasData(Initialize.Manager("test", "test@123"));

        builder.Entity<IdentityUserRole<string>>().HasData(new IdentityUserRole<string>
        {
            RoleId = SeedingIDs.RoleID,
            UserId = SeedingIDs.ManagerID
        });

    }
MOHAMED ABUELATTA
  • 305
  • 2
  • 5
  • 15