我喜歡在沒有事件源的情況下嘗試CQRS的想法。 但我不知道如何解決這個事實,我需要給用戶一個即時反饋。CQRS中的驗證和同步命令
這是我目前的註冊(簡化了解) 我使用Dapper讀取和nHibernate寫入。
signupcontroller.cs
public ActionResult signup(UserCreateModel model)
{
// model validation (email, password strength etc)
if (!ModelState.IsValid)
{
// get back to form and show errors
}
// use service layer to validate against database and create user
var registermodel = _userService.create_user_account(model.username, model.email, model.password);
// service returns and object with several states
if (registermodel.Status == UserRegistrationStatus.Ok)
{
// user registered ok, display thank you or whatever
}
if (registermodel.Status == UserRegistrationStatus.DuplicatedUsername)
{
// duplicated username found, back to form and show errors
}
if (registermodel.Status == UserRegistrationStatus.DuplicatedEmail)
{
// duplicated email found, back to form and show errors
}
// get back to form and show errors
}
哪個appraoches的將是最CQRS友好嗎?
方法1
signupcontroller.cs
public ActionResult signup(UserCreateModel model)
{
// model validation (email, password strength etc)
if (!ModelState.IsValid)
{
// get back to form and show errors
}
// validate duplicated email
bool is_email_duplicated = _read.user_email_exists(model.email);
// duplicated email found, back to form and show errors
// validate duplicated username
bool is_username_duplicated = _read.user_username_exists(model.username);
// duplicated username found, back to form and show errors
// assume all is perfect and dispatch
_commandDispatcher.Dispatch(new CreateUserCommand(model.username, model.email, model.password));
}
如果我需要做相同的驗證中某處系統(我會重複的代碼)?
我想過創建ValidationService。
如果命令「爆炸」出於某種原因該怎麼辦?用戶將得到錯誤的反饋?
方法2
signupcontroller.cs
public ActionResult signup(UserCreateModel model)
{
// model validation (email, password strength etc)
if (!ModelState.IsValid)
{
// get back to form and show errors
}
// dispatch and validate inside the handler, abort execution if validation failed
var command = new CreateUserCommand(model.username, model.email, model.password)
// attached common feedback object to the command and deal with errors
if(command.status == UserRegistrationStatus.DuplicatedUsername)
{
// get back to form and show errors
}
}
基本上處理機我欺騙和驗證(增加額外的方法來的nHibernate回購)的內部。
方法3
類似於第一種方法,但內UserService封裝驗證和調度
signupcontroller.cs
public ActionResult signup(UserCreateModel model)
{
// model validation (email, password strength etc)
if (!ModelState.IsValid)
{
// get back to form and show errors
}
var feedback = _userService.create_user(model.username, model.email, model.password);
// check for status and return feedback to the user
}
userservice.cs
public Feedback create_user(string username, string email, string password)
{
// validate duplicated email
bool is_email_duplicated = _read.user_email_exists(email);
// duplicated email found, back to form and show errors
// validate duplicated username
bool is_username_duplicated = _read.user_username_exists(username);
// duplicated username found, back to form and show errors
// dispatch command
_commandDispatcher.Dispatch(new CreateUserCommand(username, email, password));
}
我喜歡這種方法,但我覺得它會成爲一個Baklava代碼。
可以完美把你的「閱讀」添加到你的CommandHandler中。畢竟,在您決定創建新的AR或修改某些內容之前,CommandHandler中沒有任何事情發生。你可以很好的從你的CommandHandler中拋出一個異常,讓控件處理它。 –