Created
January 3, 2017 00:49
-
-
Save dasjestyr/85809695e6ff2d28fedd1f9119aeb4eb to your computer and use it in GitHub Desktop.
Example class layout for a domain aggregate in a command model
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| public class Employee : Aggregate | |
| { | |
| private readonly IAccountService _accountService; | |
| // all mutable properties are private there is no reason to expose these as properties | |
| // in the write model | |
| private string _firstName; | |
| private string _lastName; | |
| public Employee(IAccountService accountService) | |
| { | |
| _accountService = accountService; | |
| } | |
| // public interface exposes semantic operations, using the ubiquitous language | |
| public void CreateNew(Guid accountId, string firstName, string lastName) | |
| { | |
| // always do validation in the public method. This is the chance for the aggregate to refuse the | |
| // request | |
| var accountIsActive = _accountService.AccountIsActive(accountId); | |
| if(!accountIsActive) | |
| throw new InvalidOperationException("Cannot create employee on an inactive account.") | |
| if(Id != null) | |
| throw new InvalidOperationException("This instance appears to have already been created."); | |
| if(string.IsNullOrEmpty(firstName)) | |
| throw new ArgumentNullException(nameof(firstName)); | |
| if(string.IsNullOrEmpty(lastName)) | |
| throw new ArgumentNullException(nameof(lastName)); | |
| /*********************************************************************************************** | |
| * Don't actually set the state in the public method, let the event handler take care of that | |
| * this ensures the event only fires if the aggregate approves the operation and also prevents | |
| * us for having state set in two different places since Apply is how the event store restores | |
| * the state of the object | |
| ***********************************************************************************************/ | |
| // Dynamic method on the base class | |
| ApplyEvent(new CreateEmployee(Guid.NewGuid(), firstName, lastName)); | |
| } | |
| // private Apply methods simply modify the objects state. This method is called dynamically | |
| // from the Aggregate base class | |
| private void Apply(CreateEmployee e) | |
| { | |
| Id = e.Id; // exists on base class | |
| _firstName = e.FirstName; | |
| _lastName = e.LastName; | |
| } | |
| // snapshots are how we get state out of this protected object | |
| public override EmployeeSnapshot GetSnapshot() | |
| { | |
| return new EmployeeSnapshot | |
| { | |
| Id = Id, | |
| FirstName = _firstName, | |
| LastName = _lastName | |
| }; | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment