如何注册自定义UserStore& DI中的UserManager [英] How to register custom UserStore & UserManager in DI

查看:65
本文介绍了如何注册自定义UserStore& DI中的UserManager的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的设置:

public class ApplicationUser : IdentityUser<Guid>
{
}
public class ApplicationRole : IdentityRole<Guid>
{
}
public class ApplicationUserLogin : IdentityUserLogin<Guid>
{
}
public class ApplicationUserClaim : IdentityUserClaim<Guid>
{
}
public class ApplicationRoleClaim : IdentityRoleClaim<Guid>
{
}

这是我的UserStore的定义

Here is the definition of my UserStore

public class ApplicationUserStore : UserStore<ApplicationUser, ApplicationRole, MyContext, Guid>
{
    public ApplicationUserStore(MyContext context, IdentityErrorDescriber describer = null)
        : base(context, describer)
    {
    }
}

这是我的UserManager的定义

Here is the definition of my UserManager

public class ApplicationUserManager : UserManager<ApplicationUser>
{
    public ApplicationUserManager(IUserStore<ApplicationUser> store, IOptions<IdentityOptions> optionsAccessor,
        IPasswordHasher<ApplicationUser> passwordHasher, IEnumerable<IUserValidator<ApplicationUser>> userValidators,
        IEnumerable<IPasswordValidator<ApplicationUser>> passwordValidators, ILookupNormalizer keyNormalizer,
        IdentityErrorDescriber errors, IEnumerable<IUserTokenProvider<ApplicationUser>> tokenProviders,
        ILoggerFactory logger, IHttpContextAccessor contextAccessor)
        : base(
            store, optionsAccessor, passwordHasher, userValidators, passwordValidators, keyNormalizer, errors,
            tokenProviders, logger, contextAccessor)
    {
    }
}

这是我的DbContext的定义:

Here is the definition of my DbContext:

public class MyContext : IdentityDbContext<ApplicationUser, ApplicationRole, Guid>
{
    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);
    }
}

这是我的Startup.cs

And here is my Startup.cs

    public IServiceProvider ConfigureServices(IServiceCollection services)
    {
        services.AddMvc();

        services.AddEntityFramework()
            .AddSqlServer()
            .AddDbContext<MyContext>(options => options.UseSqlServer(Configuration.Get("Data:DbConnection")));

        services.AddIdentity<ApplicationUser, ApplicationRole>()
            .AddEntityFrameworkStores<MyContext, Guid>()
            .AddUserStore<ApplicationUserStore>()
            .AddRoleStore<ApplicationRoleStore>()
            .AddUserManager<ApplicationUserManager>()
            .AddRoleManager<ApplicationRoleManager>()
            .AddDefaultTokenProviders();

        var builder = new ContainerBuilder();
        builder.Populate(services);
        var container = builder.Build();
        return container.Resolve<IServiceProvider>();
    }

此构造函数的依赖项将起作用:

The dependency of this constructor will work:

public AccountController(UserManager<ApplicationUser> userManager, SignInManager<ApplicationUser> signInManager)

这不会:

public AccountController(ApplicationUserManager userManager, SignInManager<ApplicationUser> signInManager)

有人知道我在做什么错吗?

Anyone has an idea on what I'm doing wrong?

推荐答案

DI通常用于接口驱动的开发. .AddUserManager<ApplicationUserManager>()指定实现UserManager<>,而不是服务接口.这意味着它仍然期望您获得UserManager<ApplicationUser>并仅以这种方式使用它.它会给你一个ApplicationUserManager.

DI in general is intended for interface-driven development; .AddUserManager<ApplicationUserManager>() specifies an implementation UserManager<>, not the service interface. That means that it's still expecting you to get UserManager<ApplicationUser> and only use it that way; it'll give you an ApplicationUserManager.

我假设您要在ApplicationUserManager上使用其他方法. 如果不是, 只需按照其工作方式使用依赖项构造函数,并享受界面驱动的开发.如果是,则有3个选择:

I'm assuming that you have additional methods you want to use on your ApplicationUserManager. If not, just use the dependency constructor the way it works and enjoy the interface-driven development. If so, you have 3 options:

  1. 通过组合而不是继承来使用扩展.与其从UserManager<>继承,不如将其写为包装类.您可以将其包含在构造函数中.这应该为您提供ApplicationUserManager内部所需的所有功能.

  1. Use extension via composition rather than inheritance. Rather than inheriting from UserManager<>, write ApplicationUserManager as a wrapper class; you can include it in the constructor. This should give you all the functionality you need inside of the ApplicationUserManager.

自己将其按原样添加到DI框架中.这并不像听起来那样困难,因为UserManager<>本身没有真实状态:

Add it as-is to the DI framework yourself. This isn't as difficult as it sounds, since the UserManager<> has no real state itself:

services.AddScoped<ApplicationUserManager>();

此处的缺点是您实际上将有两个UserManager<>对象用于用户范围.结果可能是效率低下.从当前代码的状态来看,我认为不是.

The disadvantage here is that you'll actually have two UserManager<> objects for the user's scope; there could be some inefficiencies as a result. From the state of the current code, I don't think it is.

将其写为扩展方法.如果您有很多依赖关系,而不仅仅是UserManager<>的基本功能,那么这可能会很复杂.

Write it as extension methods. If you have a number of dependencies and not just the UserManager<>'s base functionality, this could be really complex.

这篇关于如何注册自定义UserStore&amp; DI中的UserManager的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆