简体   繁体   English

在通用存储库模式中使用ApplicationUser

[英]Using ApplicationUser in a Generic Repository pattern

Is it possible to use asp net core's default authentication in a generic repository pattern and if so, how? 是否可以在通用存储库模式中使用asp net core的默认身份验证,如果可以,如何使用?

I am able to create a project that uses a generic repository pattern for all of my code, except the authentication side of the project which uses the default way. 我能够创建一个对所有代码都使用通用存储库模式的项目,但使用默认方式的项目的身份验证方除外。

My repository looks like: 我的存储库如下所示:

using System.Linq;
using DemoWebsite.Interfaces;
using Microsoft.EntityFrameworkCore;

namespace DemoWebsite.Data
{
 public class Repository<T> : IRepository<T> where T : class
{
    protected readonly DbContext Context;
    protected DbSet<T> DbSet;

    public Repository(ApplicationDbContext context)
    {
        Context = context;
        DbSet = context.Set<T>();
    }

    public void Add(T entity)
    {
        Context.Set<T>().Add(entity);

        Save();
    }

    public T Get<TKey>(TKey id)
    {
        return DbSet.Find(id);
    }

    public IQueryable<T> GetAll()
    {
        return DbSet;
    }

    public void Update(T entity)
    {
        Save();
    }

    private void Save()
    {
        Context.SaveChanges();
    }
}
}

My ApplicationDbContext class: 我的ApplicationDbContext类:

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
        : base(options)
    {
    }

    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);
        // Customize the ASP.NET Identity model and override the defaults if needed.
        // For example, you can rename the ASP.NET Identity table names and more.
        // Add your customizations after calling base.OnModelCreating(builder);
    }
}

Yes it's possible, but it's quite a bit of effort to do so. 是的,这是可能的,但是这样做需要很多努力。 You'll have to Implement IUserStore and possibly IRoleStore (interfaces here and here ). 您将必须实现IUserStore以及可能的IRoleStore此处此处的接口)。

When implementing this interfaces, you also have to implement all of the feature interfaces (for getting passwords, two-factor authentication ( here ), security stamp, etc.). 在实现此接口时,还必须实现所有功能接口(用于获取密码,两因素身份验证( 在此处 ),安全标记等)。

For an example implementation you can always look at the source of the EF Core Identity provider . 对于示例实现,您始终可以查看EF Core Identity提供程序的来源。

Like this 像这样

public abstract class UserStore<TUser, TRole, TContext, TKey, TUserClaim, TUserRole, TUserLogin, TUserToken, TRoleClaim> :
    IUserLoginStore<TUser>,
    IUserRoleStore<TUser>,
    IUserClaimStore<TUser>,
    IUserPasswordStore<TUser>,
    IUserSecurityStampStore<TUser>,
    IUserEmailStore<TUser>,
    IUserLockoutStore<TUser>,
    IUserPhoneNumberStore<TUser>,
    IQueryableUserStore<TUser>,
    IUserTwoFactorStore<TUser>,
    IUserAuthenticationTokenStore<TUser>
    where TUser : IdentityUser<TKey, TUserClaim, TUserRole, TUserLogin>
    where TRole : IdentityRole<TKey, TUserRole, TRoleClaim>
    where TContext : DbContext
    where TKey : IEquatable<TKey>
    where TUserClaim : IdentityUserClaim<TKey>
    where TUserRole : IdentityUserRole<TKey>
    where TUserLogin : IdentityUserLogin<TKey>
    where TUserToken : IdentityUserToken<TKey>
    where TRoleClaim : IdentityRoleClaim<TKey>
{
    ...
}

Your user store could look like: 您的用户商店可能看起来像:

public class GenericUserStore<TUser> : IUserStore<TUser>,
    IUserPasswordStore<TUser> where TUser : ApplicationUser
{
    public GenericUserStore(IRepository<TUser> userRepo) { }

    public Task<TUser> FindByIdAsync(string userId, CancellationToken cancellationToken)
    {
        return userRepo.Get(userId);
    }

    ...
}

and same for RoleStore . RoleStore相同。 Then finally replace the EF Provider registration with your own ones (source of EF here ). 然后,用您自己的EF Provider注册替换EF Provider注册( 此处是EF的来源)。

userStoreType = typeof(GenericUserStore<,,,>).MakeGenericType(userType, roleType, contextType, keyType);
roleStoreType = typeof(GenericRoleStore<,,>).MakeGenericType(roleType, contextType, keyType);

var services = new ServiceCollection();
services.AddScoped(
    typeof(IUserStore<>).MakeGenericType(userType),
    userStoreType);
services.AddScoped(
    typeof(IRoleStore<>).MakeGenericType(roleType),
    roleStoreType);

Then UserManager and other Identity classes will use your User/Role store. 然后, UserManager和其他Identity类将使用您的用户/角色存储。 But it's more trouble then it's worth, unless you have an existing DB structure which can't be mapped to EF/known providers. 但这要麻烦的多是值得的,除非您具有无法映射到EF /已知提供程序的现有数据库结构。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM