danielcirket / OpenEventSourcing

MIT License
3 stars 0 forks source link

Conflict resolution #9

Closed danielcirket closed 5 years ago

danielcirket commented 5 years ago

In many cases concurrency errors can be easily resolved without having to return the client an error.

Using a customer as an example, changing a customers name shouldn't conflict with an delivery address change, in this case you should be able to simply rebase the name change after the address change.

This behaviour would most-often be defined by the business requirements and processes so allowing consumers to optionally provide/consume these in CommandHandlers / Saving an aggregate would be preferable.

By default, the implementations should simply noop and rethrow the error I suspect, and once additional implementations are supplied use those to attempt conflict resolution.

My initial thoughts are:

public interface IConcurrencyConflictResolver<TAggregate>
{
 Task /* What should we return here, if anything? */ ResolveAsync(TAggregate aggregate, IEnumerable<IEvent> conflictingEvents);
}
public MyCommandHandler : ICommandHandler<TCommand>
{
    public MyCommandHandler(/* ... */, IConcurrencyConflictResolver<MyAggregate> conflictResolver) 
    {
         /* ... */ 
    }
}

This is subject to change as I think this through and get feedback from others.

danielcirket commented 5 years ago

Out of scope at this time