A solution to build EventSourced components
Clone or download
Latest commit ca66742 Mar 22, 2018
Permalink
Failed to load latest commit information.
src bumped version to 4.0.3 Mar 21, 2018
.gitignore Initial commit Jul 26, 2016
.travis.yml fixed readme and travis ci May 1, 2017
LICENSE Initial commit Jul 26, 2016
README.md updated readme Mar 17, 2018

README.md

Evento

This C# library can be used to build event sourced components.

It is not related to a particular storage. It's available in a separate project a concrete Repository class using GetEventStore https://github.com/EventStore/EventStore

You can find more info in my blog http://www.dinuzzo.co.uk/2017/04/28/domain-driven-design-event-sourcing-and-micro-services-explained-for-developers/

The 'Evento' library has no-dependencies therefore it can be referenced by Domain projects and Application Service projects. You can see a Sample project showing how to use this library https://github.com/riccardone/Evento.Samples

You can reference this project using Nuget

PM> Install-Package Evento  

Evento.Repository

This .Net 4.6.1 C# library contains a concrete EventStoreDomainRepository with external dependencies to EventStore.Client v4.X and Newton.Json v10.X This library can be referenced and used in the top level host process application and injected into any Application Service that requires an IDomainRepository.

You can reference this project using Nuget

PM> Install-Package Evento.Repository

Use the EventStore DomainRepository

The IDomainRepository interface expose two methods: 'Save' and GetById. The Save method take an IAggregate as parameter and a correlationId. The correlationId is used to link toghether the events that are part of the same conversation. It defines the AggregateId and when the events are stored in EventStore it is used to define the StreamId.

example creating an EventStoreDomainRepository with the word 'domain' as category

var repository = new EventStoreDomainRepository("domain", Configuration.CreateConnection("MyAdapterConnection"));

Use AggregateBase and IAggregate to build your Aggregates

namespace Domain.Aggregates
{
    public class AssociateAccount : AggregateBase
    {
        public override string AggregateId => CorrelationId;
        private string CorrelationId { get; set; }
        private Guid AssociateId { get; set; }
        private List<Income> Incomes { get; }
        private List<Expense> Expenses { get; }

        public AssociateAccount(Guid associateId, IDictionary<string, string> metadata) : this()
        {
            RaiseEvent(new AssociateAccountCreated(associateId, metadata));
        }

        public AssociateAccount()
        {
            Incomes = new List<Income>();
            Expenses = new List<Expense>();
            RegisterTransition<AssociateAccountCreated>(Apply);
            RegisterTransition<IncomeRegistered>(Apply);
            RegisterTransition<ExpenseRegistered>(Apply);
        }
        private void Apply(AssociateAccountCreated evt)
        {
            CorrelationId = evt.Metadata["$correlationId"];
            AssociateId = evt.AssociateId;
        }
        public static IAggregate Create(CreateAssociateAccount createAssociateAccount)
        {
            Ensure.NotNull(createAssociateAccount, nameof(createAssociateAccount));
            Ensure.NotEmptyGuid(createAssociateAccount.AssociateId, nameof(createAssociateAccount.AssociateId));

            return new AssociateAccount(createAssociateAccount.AssociateId, createAssociateAccount.Metadata);
        }
        
        // ....
    }