Create an User in a Console .NET Core Application

a 夏天 提交于 2019-12-21 04:55:05

问题


I have a ASP.NET Core 1.0 Solution with 3 projects (Web, Console Application, DataAccessLayer). I use ASP.NET Core Identity and Entity Framework Core (SQL Server - Code First).

In my Console Application (Used for background tasks), I want to create users, but how I can have access to UserManager object in a Console Application (Or in a .NET Core Class Library) ?

In a controller class, it's easy with Dependency Injection :

public class AccountController : Controller  {
private readonly UserManager<ApplicationUser> _userManager;

public AccountController(UserManager<ApplicationUser> userManager, SignInManager<ApplicationUser> signInManager)
{
    _userManager = userManager;
}

//...

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Register(RegisterViewModel model)
{
    var user = new ApplicationUser { UserName = model.Email, Email = model.Email };
    var result = await _userManager.CreateAsync(user, model.Password);

    //...
}

How I can do the equivalent in a Console Core Application ?


回答1:


Thanks to Tseng's answer I ended up with this code. Just in case if someone would need:

public class Program
    {
        private interface IUserCreationService
        {
            Task CreateUser();
        }

        public static void Main(string[] args)
        {
            var services = new ServiceCollection();

            services.AddDbContext<ApplicationDbContext>(
            options =>
            {
                options.UseSqlServer("Server=(localdb)\\mssqllocaldb;Database=my-app-db;Trusted_Connection=True;MultipleActiveResultSets=true");
            });

            // Authentification
            services.AddIdentity<ApplicationUser, IdentityRole>(opt =>
            {
                // Configure identity options
                opt.Password.RequireDigit = false;
                opt.Password.RequireLowercase = false;
                opt.Password.RequireUppercase = false;
                opt.Password.RequireNonAlphanumeric = false;
                opt.Password.RequiredLength = 6;
                opt.User.RequireUniqueEmail = true;
            })
                .AddEntityFrameworkStores<ApplicationDbContext>()
                .AddDefaultTokenProviders();

            services.AddScoped<IUserCreationService, UserCreationService>();

            // Build the IoC from the service collection
            var provider = services.BuildServiceProvider();

            var userService = provider.GetService<IUserCreationService>();

            userService.CreateUser().GetAwaiter().GetResult();

            Console.ReadKey();
        }

        private class UserCreationService : IUserCreationService
        {
            private readonly UserManager<ApplicationUser> userManager;

            public UserCreationService(UserManager<ApplicationUser> userManager)
            {
                this.userManager = userManager;
            }

            public async Task CreateUser()
            {
                var user = new ApplicationUser { UserName = "TestUser", Email = "test@example.com" };
                var result = await this.userManager.CreateAsync(user, "123456");

                if (result.Succeeded == false)
                {
                    foreach (var error in result.Errors)
                    {
                        Console.WriteLine(error.Description);
                    }
                }
                else
                {
                    Console.WriteLine("Done.");
                }
            }
        }
    }



回答2:


In my Console Application (Used for background tasks), I want to create users, but how I can have access to UserManager object in a Console Application (Or in a .NET Core Class Library) ?

Same as you do it in ASP.NET Core. You just need to bootstrap it yourself. Inside your Main (which is the console applications composition root - the earliest point where you can set up your object graph).

Here you create a ServiceCollection instance, register the services and build the container, then resolve your app entry point. From there, anything else goes via DI.

public static int Main(string[] args)
{
    var services = new ServiceCollection();
    // You can use the same `AddXxx` methods you did in ASP.NET Core
    services.AddIdentity();
    // Or register manually
    services.AddTransient<IMyService,MyService();
    services.AddScoped<IUserCreationService,UserCreationService>();
    ...

    // build the IoC from the service collection
    var provider = services.BuildServiceProvider();

    var userService = provider.GetService<IUserCreationService>();

    // we can't await async in Main method, so here this is okay
    userService.CreateUser().GetAwaiter().GetResult();
}

public class UserCreationService : IUserCreationService 
{
    public UserManager<ApplicationUser> userManager;

    public UserCreationService(UserManager<ApplicationUser> userManager)
    {
        this.userManager = userManager;
    } 

    public async Task CreateUser() 
    {
        var user = new ApplicationUser { UserName = "TestUser", Email = "test@example.com" };
        var result = await _userManager.CreateAsync(user, model.Password);
    }
}

In practice the first class you resolve wouldn't be your UserCreationService but some MainApplication class, which is the core of your application and responsible for keeping the application alive as long as the operation happens, i.e. if its a background worker you run some kind of host (Azure Web Job Host etc.) which keeps the application running so it can receive events from outside (via some message bus) and on each event starts a specific handler or action, which in turn resolves other services etc.




回答3:


I know this answer is late, but other people might benefit.

You are seriously overcomplicating things using services etc. You can just do:

var userStore = new UserStore<ApplicationUser>(new ApplicationDbContext());
var manager = new ApplicationUserManager(userStore);
var result = await manager.Create(user, password);

If you still want all the password validation functionality just add it to the constructor of ApplicationUserManager



来源:https://stackoverflow.com/questions/40605950/create-an-user-in-a-console-net-core-application

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!