Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Projections #54

Merged
merged 60 commits into from
Apr 9, 2021
Merged

Projections #54

merged 60 commits into from
Apr 9, 2021

Conversation

woksin
Copy link
Contributor

@woksin woksin commented Mar 29, 2021

Summary

Adds Projections, that are a special type of event handler dealing with read models. Projections can be defined either inline in the client build steps, or declaratively with [Projection()] attribute.

Example of writing a Projection inline and registering a declared one:

var client = Client
    .ForMicroservice("f39b1f61-d360-4675-b859-53c05c87c0e6")
    .WithEventTypes(eventTypes =>
    {
        eventTypes.Register<DishPrepared>();
        eventTypes.Register<ChefFired>();
    })
    .WithProjections(projections =>
    {
        projections.CreateProjection("4a4c5b13-d4dd-4665-a9df-27b8e9b2054c")
            .ForReadModel<Chef>()
            .On<DishPrepared>(_ => _.KeyFromProperty(_ => _.Chef), (chef, @event, ctx) =>
            {
                chef.Name = @event.Chef;
                chef.Dishes.Add(@event.Dish);
                return chef;
            })
            .On<ChefFired>(_ => _.KeyFromProperty(_ => _.Chef), (chef, @event, ctx) =>
            {
                return ProjectionResult<Chef>.Delete;
            });
        projections.RegisterProjection<Menu>();
    })
    .Build();

Example of a declared projection:

[Projection("0405b93f-1461-472c-bdc2-f89e0afd4dfe")]
public class Menu
{
    public List<string> Dishes = new List<string>();

    [KeyFromEventSource]
    public void On(DishPrepared @event, ProjectionContext context)
    {
        if (!Dishes.Contains(@event.Dish)) Dishes.Add(@event.Dish);
    }
}

Example of getting projections:

var menu = await client.Projections
    .ForTenant(TenantId.Development)
    .Get<Menu>("bfe6f6e4-ada2-4344-8a3b-65a3e1fe16e9")
    .ConfigureAwait(false);

System.Console.WriteLine($"Menu consists of: {string.Join(", ", menu.State.Dishes)}");

var allChefs = await client.Projections
    .ForTenant(TenantId.Development)
    .GetAll<Chef>()
    .ConfigureAwait(false);

foreach (var chef in allChefs)
{
    System.Console.WriteLine($"Chef name: {chef.State.Name} and prepared dishes: {string.Join(",", chef.State.Dishes)}");
}

Added

  • New client.WithProjections() to build Projections inline in the clients build steps.
  • Classes can be attributed with[Projection('projectionId')] to declare them as Projections (just like you can do with EventHandlers). The class itself becomes the readmodel for the projection.
  • On() methods are the handlers for a Projection. They can be decorated with different attributes to declare the key to the projection.
  • Get the state of a Projection with client.Projections.Get<ReadModel>(key) and client.Projections.GetAll<ReadModel>() (+ other overloads).
  • Sample for how to use Projections in Samples/Tutorials/Projections.

Changed

  • Sample directory structure and moved the tutorials around

@woksin woksin marked this pull request as draft March 29, 2021 18:10
@woksin woksin added the minor label Mar 29, 2021
woksin and others added 27 commits March 30, 2021 22:35
Co-authored-by: Joel Hoisko <joel.hoisko@gmail.com>
Co-authored-by: Jakob Høgenes <jakhog@users.noreply.github.com>
Co-authored-by: Joel Hoisko <joel.hoisko@gmail.com>
Co-authored-by: Jakob Høgenes <1014990+jakhog@users.noreply.github.com>
Co-authored-by: Jakob Høgenes <1014990+jakhog@users.noreply.github.com>
Co-authored-by: Jakob Høgenes <1014990+jakhog@users.noreply.github.com>
Co-authored-by: Jakob Høgenes <1014990+jakhog@users.noreply.github.com>
Co-authored-by: Jakob Høgenes <1014990+jakhog@users.noreply.github.com>
Co-authored-by: Jakob Høgenes <1014990+jakhog@users.noreply.github.com>
Co-authored-by: Jakob Høgenes <1014990+jakhog@users.noreply.github.com>
Co-authored-by: Jakob Høgenes <1014990+jakhog@users.noreply.github.com>
Co-authored-by: Jakob Høgenes <1014990+jakhog@users.noreply.github.com>
Co-authored-by: Jakob Høgenes <1014990+jakhog@users.noreply.github.com>
Co-authored-by: Jakob Høgenes <1014990+jakhog@users.noreply.github.com>
Co-authored-by: Jakob Høgenes <1014990+jakhog@users.noreply.github.com>
…r.cs

Co-authored-by: Jakob Høgenes <1014990+jakhog@users.noreply.github.com>
…r.cs

Co-authored-by: Jakob Høgenes <1014990+jakhog@users.noreply.github.com>
woksin and others added 15 commits April 7, 2021 12:48
Co-authored-by: Jakob Høgenes <1014990+jakhog@users.noreply.github.com>
Co-authored-by: Jakob Høgenes <1014990+jakhog@users.noreply.github.com>
…ion.cs

Co-authored-by: Jakob Høgenes <1014990+jakhog@users.noreply.github.com>
Co-authored-by: Jakob Høgenes <1014990+jakhog@users.noreply.github.com>
Co-authored-by: Jakob Høgenes <1014990+jakhog@users.noreply.github.com>
Co-authored-by: Jakob Høgenes <1014990+jakhog@users.noreply.github.com>
Co-authored-by: Jakob Høgenes <1014990+jakhog@users.noreply.github.com>
@joelhoisko joelhoisko changed the title Format + add projection prerelease branch Projections Apr 8, 2021
@joelhoisko joelhoisko marked this pull request as ready for review April 9, 2021 10:38
@jakhog jakhog merged commit 5a85f2e into master Apr 9, 2021
@jakhog jakhog deleted the 8.4.0-projections branch April 9, 2021 10:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants