2017-02-16 80 views
0

我想实现UserStore,但我也想实现UserEmailStore和UserLockoutStore和其他人。正如我注意到所有用户*商店都基于UserStore,没有问题。但是我看了一下UserManager,发现了对我来说很奇怪的事情。您可以向UserManager注入多种类型的商店,但始终只有一种。但是UserManager可以根据你注入的类型来处理它们。用户管理器用于不同的商店(UserStore,UserEmailStore,UserClaimStore,UserLockoutStore等)

福克斯示例方法GetLockoutEndDateAsync从的UserManager

public virtual async Task<DateTimeOffset?> GetLockoutEndDateAsync(TUser user) 
{ 
    this.ThrowIfDisposed(); 
    IUserLockoutStore<TUser> userLockoutStore = this.GetUserLockoutStore(); 
    if ((object) user == null) 
    throw new ArgumentNullException("user"); 
    TUser user1 = user; 
    CancellationToken cancellationToken = this.CancellationToken; 
    return await userLockoutStore.GetLockoutEndDateAsync(user1, cancellationToken); 
} 

方法this.GetUserLockoutStore看起来像这样

internal IUserLockoutStore<TUser> GetUserLockoutStore() 
{ 
    IUserLockoutStore<TUser> userLockoutStore = this.Store as IUserLockoutStore<TUser>; 
    if (userLockoutStore != null) 
    return userLockoutStore; 
    throw new NotSupportedException(Resources.StoreNotIUserLockoutStore); 
} 

还有其他的方法,如

  • GetEmailStore
  • GetPhoneNumberStore
  • GetClaimStore
  • GetLoginStore
  • ...

因此,这意味着商店必须根据要使用正确的接口上。

我的问题是,该如何处理?我应该根据所有可能的User * Store界面实施一个商店吗?或者你能提出另一种解决方案吗

在此先感谢

回答

1

是,在一个单店实现所需的接口“功能”的是简单的方法来做到这一点,这也是ASP.NET核心身份EF核心供应商是如何实现(见here

/// <summary> 
/// Represents a new instance of a persistence store for the specified user and role types. 
/// </summary> 
/// <typeparam name="TUser">The type representing a user.</typeparam> 
/// <typeparam name="TRole">The type representing a role.</typeparam> 
/// <typeparam name="TContext">The type of the data context class used to access the store.</typeparam> 
/// <typeparam name="TKey">The type of the primary key for a role.</typeparam> 
/// <typeparam name="TUserClaim">The type representing a claim.</typeparam> 
/// <typeparam name="TUserRole">The type representing a user role.</typeparam> 
/// <typeparam name="TUserLogin">The type representing a user external login.</typeparam> 
/// <typeparam name="TUserToken">The type representing a user token.</typeparam> 
/// <typeparam name="TRoleClaim">The type representing a role claim.</typeparam> 
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> 
{ 
} 

您只需要实现您将要支持的接口并将其他接口关闭。

如果由于某种原因(单一职责原则),这是不可能的(即因为您需要使用完全不同类型的数据库或一些Web服务或Active Directory),那么您可以实现单独的商店并使用外观模式环绕它,并注入你的个人商店到门面并注入门面。

但它更多的工作,并需要更多的设置DI来做到这一点。但可行。

+0

这正是我需要的。谢谢。 –

相关问题