Skip to content

Instantly share code, notes, and snippets.

@dasjestyr
Created January 3, 2017 00:49
Show Gist options
  • Select an option

  • Save dasjestyr/85809695e6ff2d28fedd1f9119aeb4eb to your computer and use it in GitHub Desktop.

Select an option

Save dasjestyr/85809695e6ff2d28fedd1f9119aeb4eb to your computer and use it in GitHub Desktop.
Example class layout for a domain aggregate in a command model
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