NEventLite 1.0.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package NEventLite --version 1.0.0                
NuGet\Install-Package NEventLite -Version 1.0.0                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="NEventLite" Version="1.0.0" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add NEventLite --version 1.0.0                
#r "nuget: NEventLite, 1.0.0"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install NEventLite as a Cake Addin
#addin nuget:?package=NEventLite&version=1.0.0

// Install NEventLite as a Cake Tool
#tool nuget:?package=NEventLite&version=1.0.0                

NEventLite - A lightweight .NET framework for Event Sourcing with support for custom Event and Snapshot Stores (EventStore, Redis, SQL Server or Custom) written in C#.


NEventLite makes it easier to implement the event sourcing pattern in your .NET project. It is opinionated and enforces some patterns. The framework is built with support for custom storage providers and event bus architectures in mind. We also provide some popular event/snapshot storage provider implementations for NEventLite here. Feel free to use it as is or customize it to suit your needs.

###DISCLAIMER: You generally want to avoid "frameworks" when implementing CQRS or Event Sourcing but NEventLite will merely help get you on the rails. You can swap out every aspect of it if need be. Think of it as training wheels.

• The framework (NEventLite.csproj) targets netstandard 1.4

• Example projects target .net framework 4.6.1

• This purpose of this NEventLite is to demonstrate the Event Sourcing design pattern using .NET

Author: Dasith Wijesiriwardena

Requirements:

• A basic understanding of what Event Sourcing is. Start here https://dasith.me/2016/12/02/event-sourcing-examined-part-1-of-3/

• Installation of EventStore (Optional, There is a built in InMemoryStorageProvider too) "Event Store stores your data as a series of immutable events over time, making it easy to build event-sourced applications" - https://geteventstore.com/)

It's very easy to use once setup. Ideal for implementing the CQRS pattern.

//See how AggregateRoots, Events and StorageProviders have been setup in the Example project.
//EventStorageProvider and SnapshotStorageProvider can be injected to the Repository.
//Can be created per command or once per life time as follows.

//Load dependency resolver

async Task CreateNote() {
    using (var container = new DependencyResolver())
    {
        //Get ioc container to create our command bus
        var commandBus = container.Resolve<ICommandBus>();        

        //Create new note by sending command to the Command Bus
        Guid itemId = Guid.NewGuid();
        
        var publishResult = await commandBus.ExecuteAsync(
                     new CreateNoteCommand(Guid.NewGuid(), newItemId, -1,
                     "Test Note", "Event Sourcing System Demo", "Event Sourcing"));	   

		//This will throw an exception if the command was not published
		//You can add logic to retry the command as required
		publishResult.EnsurePublished();
    }
}

Command Handler (NoteCommandHandler.cs in example)

        public async Task HandleCommandAsync(CreateNoteCommand command)
        {
            var work = new UnitOfWork(_repository);
            var newNote = new Note(command.AggregateId, command.Title, command.Desc, command.Cat);
            work.Add(newNote);

            await work.CommitAsync();
        }

        public async Task HandleCommandAsync(EditNoteCommand command)
        {
            var work = new UnitOfWork(_repository);
            var loadedNote = await work.GetAsync<Note>(command.AggregateId, command.TargetVersion);

            loadedNote.ChangeTitle(command.Title);
            loadedNote.ChangeDescription(command.Description);
            loadedNote.ChangeCategory(command.Cat);

            await work.CommitAsync();
        }

Aggregate (Note.cs in example)

        //Commands call the constructor or methods. Which creates an event and applies it to the Aggregate.
        
        public Note(Guid id, string title, string desc, string cat):this()
        {
            //Pattern: Create the event and call ApplyEvent(Event)
            ApplyEvent(new NoteCreatedEvent(id, this.CurrentVersion, title, desc, cat, DateTime.Now));
        }    

        public void ChangeTitle(string newTitle)
        {
            ApplyEvent(new NoteTitleChangedEvent(this.Id, this.CurrentVersion, newTitle));
        }
        
        //Applying Events 
        //Note how the framework identifies the internal event handler methods though a method attribute.
        
        [InternalEventHandler]
        public void OnNoteCreated(NoteCreatedEvent @event)
        {
            CreatedDate = @event.createdTime;
            Title = @event.title;
            Description = @event.desc;
            Category = @event.cat;
        }

        [InternalEventHandler]
        public void OnTitleChanged(NoteTitleChangedEvent @event)
        {
            Title = @event.title;
        }

Implement IEventStorageProvider and ISnapshotStorage provider for storage or use the ones we provide for popular stores. See "Storage Providers" project for ready to use implementations for EventStore and Redis. More will be added.

    public interface IEventStorageProvider
    {
        Task<IEnumerable<IEvent>> GetEventsAsync(Type aggregateType, Guid aggregateId, int start, int count);
        Task<IEvent> GetLastEventAsync(Type aggregateType, Guid aggregateId);
        Task CommitChangesAsync(AggregateRoot aggregate);
    }

	public interface ISnapshotStorageProvider
    {
        int SnapshotFrequency { get; }
        Task<Snapshot.Snapshot> GetSnapshotAsync(Type aggregateType, Guid aggregateId);
        Task SaveSnapshotAsync(Type aggregateType, Snapshot.Snapshot snapshot);
    }

Notes

Please feel free to contribute and improve the code as you see fit.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp1.0 was computed.  netcoreapp1.1 was computed.  netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard1.4 is compatible.  netstandard1.5 was computed.  netstandard1.6 was computed.  netstandard2.0 was computed.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen30 was computed.  tizen40 was computed.  tizen60 was computed. 
Universal Windows Platform uap was computed.  uap10.0 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (4)

Showing the top 4 NuGet packages that depend on NEventLite:

Package Downloads
NEventLite.StorageProviders.EventStore

EventStore storage provider for NEventLite. An extensible lightweight library for .NET that manages the Aggregate lifecycle in an Event Sourced system.

NEventLite.StorageProviders.InMemory

InMemory/TextFile storage provider for NEventLite. An extensible lightweight library for .NET that manages the Aggregate lifecycle in an Event Sourced system.

NEventLite.Extensions.Microsoft.DependencyInjection

Dependency injection support for NEventLite with Microsoft.Extensions.DependencyInjection

NEventLite.Extensions.Autofac

Dependency injection support for NEventLite with Autofac

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
3.0.26 1,853 4/19/2020
3.0.24 892 4/19/2020
2.1.23 906 4/18/2020
2.0.7 1,340 4/9/2019
2.0.5 878 4/8/2019
2.0.4 731 4/8/2019
2.0.0 856 4/8/2019
1.0.0 902 5/4/2018