Inheritance, commands and event sourcing
- by Arthis
In order not to redo things several times I wanted to factorize common stuff. For Instance, let's say we have a cow and a horse. The cow produces milk, the horse runs fast, but both eat grass.
public class Herbivorous
{
public void EatGrass(int quantity)
{
var evt= Build.GrassEaten
.WithQuantity(quantity);
RaiseEvent(evt);
}
}
public class Horse : Herbivorous
{
public void RunFast()
{
var evt= Build.FastRun;
RaiseEvent(evt);
}
}
public class Cow: Herbivorous
{
public void ProduceMilk()
{
var evt= Build.MilkProduced;
RaiseEvent(evt);
}
}
To eat Grass, the command handler should be :
public class EatGrassHandler : CommandHandler<EatGrass>
{
public override CommandValidation Execute(EatGrass cmd)
{
Contract.Requires<ArgumentNullException>(cmd != null);
var herbivorous= EventRepository.GetById<Herbivorous>(cmd.Id);
if (herbivorous.IsNull())
throw new AggregateRootInstanceNotFoundException();
herbivorous.EatGrass(cmd.Quantity);
EventRepository.Save(herbivorous, cmd.CommitId);
}
}
so far so good. I get a Herbivorous object , I have access to its EatGrass function, whether it is a horse or a cow doesn't matter really. The only problem is here :
EventRepository.GetById<Herbivorous>(cmd.Id)
Indeed, let's imagine we have a cow that has produced milk during the morning and now wants to eat grass. The EventRepository contains an event MilkProduced, and then come the command EatGrass.
With the CommandHandler, we are no longer in the presence of a cow and the herbivorious doesn't know anything about producing milk . what should it do?
Ignore the event and continue , thus allowing the inheritance and "general" commands?
or throw an exception to forbid execution, it would mean only CowEatGrass, and HorseEatGrass might exists as commands ?
Thanks for your help, I am just beginning with these kinds of problem, and I would be glad to have some news from someone more experienced.