我們的團隊決定爲我們的項目使用域驅動設計架構。現在討論正在進行中,「我們可以在DDD中使用ASP.NET身份嗎?」。我們可以在域驅動設計中使用ASP.NET身份嗎?
在DDD設計中使用ASP.NET身份存在任何缺點。
我在做一個決定時很困惑。
我已經搜索過它,但我沒有任何想法。
任何幫助將是可觀的。
我們的團隊決定爲我們的項目使用域驅動設計架構。現在討論正在進行中,「我們可以在DDD中使用ASP.NET身份嗎?」。我們可以在域驅動設計中使用ASP.NET身份嗎?
在DDD設計中使用ASP.NET身份存在任何缺點。
我在做一個決定時很困惑。
我已經搜索過它,但我沒有任何想法。
任何幫助將是可觀的。
你可以使用任何你喜歡的東西。但要注意特定解決方案將會造成的污染。如果你的領域模型混淆了數百行asp.net技術類管道代碼,使你的領域邏輯難以理解,並且缺少DDD點。
在理想情況下 - 您的領域模型應該僅取決於編程語言。
另外 - 你可能會發現我很久以前執行user session related code時有用的東西。
的問題,暴露出一些誤解:
看來,你感知域模型,你把每一件在一些應用的一體化模型相反,專注於戰略模式來區分的限界上下文。將域看作是幾個鬆散相關組件的組合。然後確定你的核心領域是什麼,並在那裏應用DDD戰術模式。並非每個組件都需要DDD。其中一些人甚至不應該使用DDD。特別是 - 通用域,如認證。
DDD是技術不可知的(某些觀點),所以是的,你可以使用ASP.NET身份或任何你喜歡的圖書館。
身份驗證通常屬於應用程序層,而不屬於域層。
但是 - 如果在您的域中存在用戶/客戶端/人員的概念,則可能需要使用身份組件提供的身份。但是你必須明白,在有界的上下文中,用戶的含義不同於用戶在標識組件中的含義。這些不是同一個概念。雖然他們都指的是坐在某個地方的同一個自然人並點擊你的應用程序的GUI,但他們有兩種不同的模型(或預測),他們服務於不同的目的。所以你不應該只在有界的上下文中重用ASP.NET User類。
相反 - 單獨的上下文應該通過反腐層進行通信。基本上你必須在有界的上下文中創建一些服務(僅用於接口),以產生特定於上下文的用戶對象。在基礎設施層中實現該接口將成爲ASP.NET Identity的一個包裝,它獲得ASP.NET Identity用戶並生成相應的有界上下文用戶。
+1這是一個很好的答案,但我擔心它可能會丟失在OP上。 – MattDavey
我是DDD的新手。但是我實現了與Identity和DDD的整合。雖然我懷疑它確實堅持DDD的原則。
我開始與實體:
public partial class User : IdentityUser {
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<User> manager) {
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
// Add custom user claims here
return userIdentity;
}
/// <summary>
/// The Date the User Registered for general information purposes
/// </summary>
public DateTime DateRegistered { get; set; }
}
則接口:
public interface IUserRepository:IBaseRepository<User> {
/// <summary>
/// Register User to Identity Database
/// </summary>
/// <param name="userManager">User Manager to Handle Registration</param>
/// <param name="user">User to add to database</param>
/// <param name="password">User's password</param>
/// <returns>Identity Result</returns>
Task<IdentityResult> Register(UserManager<User, string> userManager, User user, string password);
/// <summary>
/// Login User
/// </summary>
/// <param name="signinManager">Signin Manager to handle login</param>
/// <param name="email">Email of user</param>
/// <param name="password">Password of user</param>
/// <param name="rememberMe">Boolean if the user wants to be remembered</param>
/// <returns>SignIn Status</returns>
Task<SignInStatus> Login(SignInManager<User, string> signinManager, string email, string password, bool rememberMe);
/// <summary>
/// Verify that code sent to User is valid
/// </summary>
/// <param name="signinManager">Signin Manager to handle verification</param>
/// <param name="provider">Provider of the code</param>
/// <param name="code">The code</param>
/// <param name="rememberMe">Boolean if user wants to be remembered</param>
/// <param name="rememberBrowser">Boolean if browser should be remembered</param>
/// <returns>SignIn Status</returns>
Task<SignInStatus> VerifyCode(SignInManager<User, string> signinManager, string provider, string code, bool rememberMe, bool rememberBrowser);
/// <summary>
/// Confirm email of User
/// </summary>
/// <param name="userManager">User Manager to handle confirmation</param>
/// <param name="userId">String user Id of the User</param>
/// <param name="code">User code sent in Email</param>
/// <returns>Identity Result</returns>
Task<IdentityResult> ConfirmEmail(UserManager<User, string> userManager, string userId, string code);
void ForgotPassword();
void ForgotPasswordConfirmation();
void ResetPassword();
void ResetPasswordConfirmation();
void ExternalLogin();
void SendCode();
void ExternalLoginCallback();
void ExternalLoginConfirmation();
/// <summary>
/// Log off user from the Application
/// </summary>
/// <param name="AuthenticationManager">Application Manager to handle Sign out</param>
void Logoff(IAuthenticationManager AuthenticationManager);
/// <summary>
/// Get user based on their Email
/// </summary>
/// <param name="Email">Email of user</param>
/// <returns>User</returns>
User GetUser(string Email);
/// <summary>
/// Get User by their GUID
/// </summary>
/// <param name="ID">GUID</param>
/// <returns>User</returns>
User GetUserById(string ID);
}
然後庫:
public class UserRepository : BaseRepository<User>, IUserRepository {
/// <summary>
/// Confirm email of User
/// </summary>
/// <param name="userManager">User Manager to handle confirmation</param>
/// <param name="userId">String user Id of the User</param>
/// <param name="code">User code sent in Email</param>
/// <returns>Identity Result</returns>
public async Task<IdentityResult> ConfirmEmail(UserManager<User, string> userManager, string userId, string code) =>
await userManager.ConfirmEmailAsync(userId, code);
public void ExternalLogin() {
throw new NotImplementedException();
}
public void ExternalLoginCallback() {
throw new NotImplementedException();
}
public void ExternalLoginConfirmation() {
throw new NotImplementedException();
}
public void ForgotPassword() {
throw new NotImplementedException();
}
public void ForgotPasswordConfirmation() {
throw new NotImplementedException();
}
/// <summary>
/// Get user based on their Email
/// </summary>
/// <param name="Email">Email of user</param>
/// <returns>User</returns>
public User GetUser(string Email) =>
_context.Users.Where(p => p.Email == Email).FirstOrDefault();
/// <summary>
/// Get User by their GUID
/// </summary>
/// <param name="ID">GUID</param>
/// <returns>User</returns>
public User GetUserById(string ID) =>
_context.Users.Find(ID);
/// <summary>
/// Login User
/// </summary>
/// <param name="signinManager">Signin Manager to handle login</param>
/// <param name="email">Email of user</param>
/// <param name="password">Password of user</param>
/// <param name="rememberMe">Boolean if the user wants to be remembered</param>
/// <returns>SignIn Status</returns>
public async Task<SignInStatus> Login(SignInManager<User, string> signinManager, string email, string password, bool rememberMe) =>
await signinManager.PasswordSignInAsync(email, password, rememberMe, shouldLockout: false);
/// <summary>
/// Log off user from the Application
/// </summary>
/// <param name="AuthenticationManager">Application Manager to handle Sign out</param>
public void Logoff(IAuthenticationManager AuthenticationManager) {
AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie);
}
/// <summary>
/// Register User to Identity Database
/// </summary>
/// <param name="userManager">User Manager to Handle Registration</param>
/// <param name="user">User to add to database</param>
/// <param name="password">User's password</param>
/// <returns>Identity Result</returns>
public async Task<IdentityResult> Register(UserManager<User, string> userManager, User user, string password) =>
await userManager.CreateAsync(user, password);
public void ResetPassword() {
throw new NotImplementedException();
}
public void ResetPasswordConfirmation() {
throw new NotImplementedException();
}
public void SendCode() {
throw new NotImplementedException();
}
/// <summary>
/// Verify that code sent to User is valid
/// </summary>
/// <param name="signinManager">Signin Manager to handle verification</param>
/// <param name="provider">Provider of the code</param>
/// <param name="code">The code</param>
/// <param name="rememberMe">Boolean if user wants to be remembered</param>
/// <param name="rememberBrowser">Boolean if browser should be remembered</param>
/// <returns>SignIn Status</returns>
public async Task<SignInStatus> VerifyCode(SignInManager<User, string> signinManager, string provider, string code, bool rememberMe, bool rememberBrowser) =>
await signinManager.TwoFactorSignInAsync(provider, code, isPersistent: rememberMe, rememberBrowser: rememberBrowser);
}
IService:
public interface IUserService {
/// <summary>
/// Register User to Identity Database
/// </summary>
/// <param name="userManager">User Manager to Handle Registration</param>
/// <param name="user">User to add to database</param>
/// <param name="password">User's password</param>
/// <returns></returns>
Task<IdentityResult> Register(UserManager<User, string> userManager, User user, string password);
/// <summary>
/// Login User
/// </summary>
/// <param name="signinManager">Signin Manager to handle login</param>
/// <param name="email">Email of user</param>
/// <param name="password">Password of user</param>
/// <param name="rememberMe">Boolean if the user wants to be remembered</param>
/// <returns></returns>
Task<SignInStatus> Login(SignInManager<User, string> signinManager, string email, string password, bool rememberMe);
/// <summary>
/// Verify that code sent to User is valid
/// </summary>
/// <param name="signinManager">Signin Manager to handle verification</param>
/// <param name="provider">Provider of the code</param>
/// <param name="code">The code</param>
/// <param name="rememberMe">Boolean if user wants to be remembered</param>
/// <param name="rememberBrowser">Boolean if browser should be remembered</param>
/// <returns></returns>
Task<SignInStatus> VerifyCode(SignInManager<User, string> signinManager, string provider, string code, bool rememberMe, bool rememberBrowser);
/// <summary>
/// Confirm email of User
/// </summary>
/// <param name="userManager">User Manager to handle confirmation</param>
/// <param name="userId">String user Id of the User</param>
/// <param name="code">User code sent in Email</param>
/// <returns></returns>
Task<IdentityResult> ConfirmEmail(UserManager<User, string> userManager, string userId, string code);
void ForgotPassword();
void ForgotPasswordConfirmation();
void ResetPassword();
void ResetPasswordConfirmation();
void ExternalLogin();
void SendCode();
void ExternalLoginCallback();
void ExternalLoginConfirmation();
/// <summary>
/// Log off user from the Application
/// </summary>
/// <param name="AuthenticationManager">Application Manager to handle Sign out</param>
void Logoff(IAuthenticationManager AuthenticationManager);
/// <summary>
/// Get user based on their Email
/// </summary>
/// <param name="Email">Email of user</param>
/// <returns>User</returns>
User GetUser(string Email);
/// <summary>
/// Get User by their GUID
/// </summary>
/// <param name="ID">GUID</param>
/// <returns>User</returns>
User GetUserById(string ID);
}
服務:
public class UserService : ServiceBase, IUserService {
#region Private Field
private IUserRepository _userRepository;
#endregion
#region Constructor
/// <summary>
/// Constructor to initialise User Repository
/// </summary>
/// <param name="userRepository"></param>
public UserService(IUserRepository userRepository) {
_userRepository = userRepository;
}
#endregion
#region Methods
/// <summary>
/// Confirm email of User
/// </summary>
/// <param name="userManager">User Manager to handle confirmation</param>
/// <param name="userId">String user Id of the User</param>
/// <param name="code">User code sent in Email</param>
/// <returns>Identity Result</returns>
public Task<IdentityResult> ConfirmEmail(UserManager<User, string> userManager, string userId, string code) =>
_userRepository.ConfirmEmail(userManager, userId, code);
public void ExternalLogin() {
throw new NotImplementedException();
}
public void ExternalLoginCallback() {
throw new NotImplementedException();
}
public void ExternalLoginConfirmation() {
throw new NotImplementedException();
}
public void ForgotPassword() {
throw new NotImplementedException();
}
public void ForgotPasswordConfirmation() {
throw new NotImplementedException();
}
/// <summary>
/// Get user based on their Email
/// </summary>
/// <param name="Email">Email of user</param>
/// <returns>User</returns>
public User GetUser(string Email) {
throw new NotImplementedException();
}
/// <summary>
/// Get User by their GUID
/// </summary>
/// <param name="ID">GUID</param>
/// <returns>User</returns>
public User GetUserById(string ID) {
throw new NotImplementedException();
}
/// <summary>
/// Login User
/// </summary>
/// <param name="signinManager">Signin Manager to handle login</param>
/// <param name="email">Email of user</param>
/// <param name="password">Password of user</param>
/// <param name="rememberMe">Boolean if the user wants to be remembered</param>
/// <returns>SignIn Status</returns>
public Task<SignInStatus> Login(SignInManager<User, string> signinManager, string email, string password, bool rememberMe) =>
_userRepository.Login(signinManager, email, password, rememberMe);
/// <summary>
/// Log off user from the Application
/// </summary>
/// <param name="AuthenticationManager">Application Manager to handle Sign out</param>
public void Logoff(IAuthenticationManager AuthenticationManager) {
_userRepository.Logoff(AuthenticationManager);
}
/// <summary>
/// Register User to Identity Database
/// </summary>
/// <param name="userManager">User Manager to Handle Registration</param>
/// <param name="user">User to add to database</param>
/// <param name="password">User's password</param>
public Task<IdentityResult> Register(UserManager<User, string> userManager, User user, string password) =>
_userRepository.Register(userManager, user, password);
public void ResetPassword() {
throw new NotImplementedException();
}
public void ResetPasswordConfirmation() {
throw new NotImplementedException();
}
public void SendCode() {
throw new NotImplementedException();
}
/// <summary>
/// Verify that code sent to User is valid
/// </summary>
/// <param name="signinManager">Signin Manager to handle verification</param>
/// <param name="provider">Provider of the code</param>
/// <param name="code">The code</param>
/// <param name="rememberMe">Boolean if user wants to be remembered</param>
/// <param name="rememberBrowser">Boolean if browser should be remembered</param>
/// <returns>SignIn Status</returns>
public Task<SignInStatus> VerifyCode(SignInManager<User, string> signinManager, string provider, string code, bool rememberMe, bool rememberBrowser) =>
_userRepository.VerifyCode(signinManager, provider, code, rememberMe, rememberBrowser);
#endregion
}
你是什麼意思 「在」 是什麼意思?身份管理通常是一個單獨的有限上下文。 –
@BartłomiejSzypelow我們可以在DDD中實現asp.net身份,並且有沒有與此相關的任何鏈接或文章?如果我們在DDD中實現了asp.net標識,那麼IdentityUser是否屬於域模型層,IdentityDbContext是否屬於DAL? – RajeshKannan