title: Validation and synchronous commands in CQRS
body: <p>I like the idea of trying CQRS without event sourcing. 
  But I'm not sure how to tackle the fact that I need to give user an instant feedback.  </p>
  
  <p>This is how my current signup (simplified to understand)
  I use Dapper for reads and nHibernate for writes.</p>
  
  <p><strong>signupcontroller.cs</strong></p>
  
  <pre><code> 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 
  }
  </code></pre>
  
  <h1>Which of the appraoches would be the most CQRS friendly?</h1>
  
  <h1>Method 1</h1>
  
  <p><strong>signupcontroller.cs</strong></p>
  
  <pre><code>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));
  }
  </code></pre>
  
  <p>What if I need to do the same validation somewhere else in the system (I would have duplicated code)?</p>
  
  <p>I thought about creating ValidationService.</p>
  
  <p>What if command "explodes" for some reason and user will get false feedback?</p>
  
  <h1>Method 2</h1>
  
  <p><strong>signupcontroller.cs</strong></p>
  
  <pre><code>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 
              } 
  }
  </code></pre>
  
  <p>Basically inside the handler I cheat and validate (adding extra methods to nHibernate repo).</p>
  
  <h1>Method 3</h1>
  
  <p>Similar to the first approach, but encapsulating validation and dispatch within UserService</p>
  
  <p><strong>signupcontroller.cs</strong></p>
  
  <pre><code>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
  }
  </code></pre>
  
  <p><strong>userservice.cs</strong></p>
  
  <pre><code>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));
  }
  </code></pre>
  
  <p>I like this approach but I feel it will become a Baklava code.</p>