簡體   English   中英

與不同商店(UserStore,UserEmailStore,UserClaimStore,UserLockoutStore等)一起使用的UserManager

[英]UserManager used with different stores (UserStore, UserEmailStore, UserClaimStore, UserLockoutStore etc.)

我正在嘗試實現UserStore,但我也想實現UserEmailStore和UserLockoutStore等。 正如我注意到的那樣,所有User * Store都基於UserStore,這沒問題。 但是我查看了UserManager之后,發現對我來說很奇怪。 您可以將幾種類型的商店注入到UserManager中,但始終只能注入一種。 但是UserManager可以根據您注入的類型來使用它們。

來自UserManager的Fox示例方法GetLockoutEndDateAsync

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接口實現一個商店? 還是可以建議其他解決方案?

提前致謝

是的,在單個存儲中將所需的接口實現為“功能”是實現此目的的直接方法,這也是實現ASP.NET Core Identity EF Core提供程序的方式(請參見此處

/// <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設置才能完成。 但是可行。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM