在.NET Core控制台应用程序中创建用户

10

我有一个包含3个项目(Web、控制台应用程序、数据访问层)的ASP.NET Core 1.0解决方案。 我使用ASP.NET Core Identity和Entity Framework Core(SQL Server - Code First)。

在我的控制台应用程序(用于后台任务),我想创建用户,但是我如何在控制台应用程序中(或在.NET Core类库中)访问UserManager对象呢?

在控制器类中,使用依赖注入很容易:

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);

    //...
}

我该如何在控制台核心应用程序中进行相同的操作?


2
创建一个 API 操作并从控制台程序调用“用户创建 API”不是更容易吗? - Muqeet Khan
3个回答

12

感谢Tseng的回答,我最终用了这段代码。以防有人需要:

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.");
                }
            }
        }
    }

7
在我的控制台应用程序(用于后台任务),我想创建用户,但我如何在控制台应用程序(或.NET Core类库)中访问UserManager对象?
与在ASP.NET Core中执行的方式相同。您只需要自己引导它。在您的Main(这是控制台应用程序的组合根 - 您可以设置对象图的最早点)。
在此处,您创建一个ServiceCollection实例,注册服务并构建容器,然后解析您的应用程序入口点。从那里开始,任何其他内容都通过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);
    }
}

实际上,您解决的第一个类不会是您的UserCreationService,而是一些MainApplication类,它是应用程序的核心并负责在操作发生期间保持应用程序处于活动状态,例如,如果它是一个后台工作器,则运行某种主机(Azure Web Job Host等),使应用程序保持运行状态,以便可以从外部接收事件(通过某些消息总线)并在每个事件上启动特定的处理程序或操作,进而解决其他服务等。


谢谢Tseng :) - orrel

2
我知道我回答晚了,但其他人可能会受益。
你在使用服务等方面过于复杂化了事情。 你只需要做如下操作:
var userStore = new UserStore<ApplicationUser>(new ApplicationDbContext());
var manager = new ApplicationUserManager(userStore);
var result = await manager.Create(user, password);

如果您仍然需要所有密码验证功能,只需将其添加到ApplicationUserManager的构造函数中即可。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接