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

时间:2016-11-15 09:12:56

标签: asp.net asp.net-core asp.net-core-1.0

我有一个包含3个项目的ASP.NET Core 1.0解决方案(Web,控制台应用程序,DataAccessLayer)。 我使用ASP.NET核心身份和实体框架核心(SQL Server - 代码优先)。

在我的控制台应用程序(用于后台任务)中,我想创建用户,但是如何在控制台应用程序(或在.NET核心类库)中访问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);

    //...
}

如何在控制台核心应用程序中执行等效操作?

3 个答案:

答案 0 :(得分:7)

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

答案 1 :(得分:5)

  

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

与在ASP.NET Core中执行的操作相同。你只需要自己引导它。在Main内部(这是控制台应用程序composition root - 您可以设置对象图的最早点)。

在这里,您可以创建一个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作业主机等),使应用程序保持运行,以便它可以从外部(通过一些消息总线)接收事件,并在每个事件上启动一个特定的处理程序或操作,反过来解决其他服务等。

答案 2 :(得分:0)

我知道这个答案很晚,但是其他人可能会受益。

您正在严重使用服务等使事情复杂化。 您可以这样做:

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

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