Search
You have to implement a search. However, since a lead’s contact information can be updated—first name, last name, and phone number—sales agents may not be aware of the changes applied by other agents and may want to locate leads using their con‐ tact information, including historical values. We can easily project the historical information:
public class LeadSearchModelProjection
{
public long LeadId { get; private set; }
public HashSet<string> FirstNames { get; private set; }
public HashSet<string> LastNames { get; private set; }
public HashSet<PhoneNumber> PhoneNumbers { get; private set; }
public int Version { get; private set; }
public void Apply(LeadInitialized @event)
{
LeadId = @event.LeadId;
FirstNames = new HashSet<string>(); LastNames = new HashSet<string>(); PhoneNumbers = new HashSet<PhoneNumber>();
FirstNames.Add(@event.FirstName); LastNames.Add(@event.LastName); PhoneNumbers.Add(@event.PhoneNumber);
Version = 0;
}
public void Apply(ContactDetailsChanged @event)
{
FirstNames.Add(@event.FirstName); LastNames.Add(@event.LastName); PhoneNumbers.Add(@event.PhoneNumber);
Version += 1;
}
public void Apply(Contacted @event)
{
Version += 1;
}
public void Apply(FollowupSet @event)
{
Version += 1;
}
public void Apply(OrderSubmitted @event)
{
Version += 1;
}
public void Apply(PaymentConfirmed @event)
{
Version += 1;
}
}
The projection logic uses the LeadInitialized and ContactDetailsChanged events to populate the respective sets of the lead’s personal details. Other events are ignored since they do not affect the specific model’s state.
Applying this projection logic to Casey Davis’s events from the earlier example will result in the following state:
LeadId: 12 FirstNames: ['Casey']
LastNames: ['David', 'Davis'] PhoneNumbers: ['555-2951', '555-8101']
Version: 6