/LeVent

LeVent is a .NET library to manage local events in any application

Primary LanguageC#MIT LicenseMIT

.NET Nuget The Standard - COMPLIANT The Standard Community

LeVent

LeVent is a simple .NET library designed to provide a local event subscribing/publishing capabilities to .NET developers.

How it Works

It's important to understand the ideas around the Cul-De-Sac pattern in order for you to take the most advantage of LeVent.

Assume that you have multiple Foundation Services that want to be notified when an event of any type occurs. You can create a simple EventBroker that leverages LeVent to offer the registeration and publishing capabilities as follows:

image

In the figure above, the EventBroker leverages LeVent to offer subscribing and publishing capabilities as follows:

        public ILeVentClient<Student> StudentEventClient { get; set; }

        public async ValueTask PublishStudentEventAsync(Student student) =>
            await this.StudentEventClient.PublishEventAsync(student);

        public void RegisterStudentHandler(Func<Student, ValueTask> studentHandler) =>
            this.StudentEventClient.RegisterEventHandler(studentHandler);

Then, an StudentEventService will leverage the EventBroker to allow higher-order services to register/listen or publish through that eventing mechanism as follows:

    public class StudentEventService : IStudentEventService
    {
        private readonly IEventBroker eventBroker;

        public StudentEventService(IEventBroker eventBroker) =>
            this.eventBroker = eventBroker;

        public async ValueTask PublishStudentEventAsync(Student student) =>
            await this.eventBroker.PublishStudentEventAsync(student);

        public void RegisterStudentEventHandler(Func<Student, ValueTask> studentEventHandler) =>
            this.eventBroker.RegisterStudentHandler(studentEventHandler);
    }

The next step would be for Orchestration services to either publish or listen to the event and call it's dependencies.

In the case of a publisher - a StudentOrchestrationService would be as follows:

    public class StudentOrchestrationService : IStudentOrchestrationService
    {
        private readonly IStudentEventService studentEventService;
        private readonly IStudentService studentService;

        public StudentOrchestrationService(
            IStudentEventService studentEventService,
            IStudentService studentService)
        {
            this.studentEventService = studentEventService;
            this.studentService = studentService;
        }

        public async ValueTask AddStudentAsync(Student student)
        {
            this.studentService.AddStudent(student);
            await this.studentEventService.PublishStudentEventAsync(student);
        }
    }

The Orchestration service above will add a Student first then publish an event about that student to all listeners.

Let's check out what a listener would look like:

    public class StudentLibraryOrchestrationService : IStudentLibraryOrchestrationService
    {
        private readonly IStudentEventService studentEventService;
        private readonly IStudentLibraryService studentLibraryService;

        public StudentLibraryOrchestrationService(
            IStudentEventService studentEventService,
            IStudentLibraryService studentLibraryService)
        {
            this.studentEventService = studentEventService;
            this.studentLibraryService = studentLibraryService;
        }

        public void ListenToStudentEvents()
        {
            this.studentEventService.RegisterStudentEventHandler((student) =>
            {
                this.studentLibraryService.RegisterStudentLibaryCard(student);

                return ValueTask.CompletedTask;
            });
        }

The StudentLibraryOrchestrationService will receive a Student event from whomever is publishing these events with no coupling and acts upon that very same event by creating a LibraryCard.

This pattern is called Cul-De-Sac. It's an advanced low-level architecture technique to allow scaling and chaining to infinite number of events with no coupling whatsoever - here's how it looks in the 3D space:

image

The figure above assume no dependcy between one listener and the other. You can also leverage LeVent to allow chaining of listeners as follows:

image

These patterns allow for a more maintainble standardized systems - completely decoupled from it's event source and capable of passing forward an event as an interceptor or completing a task and forwarding.

Here's the Low-Level Architecture of this library


image