Getting Started
Architecture
NServiceBus
Transports
Persistence
ServiceInsight
ServicePulse
ServiceControl
Monitoring
Samples

Cinema Showcase

Component: NServiceBus
NuGet Package: NServiceBus (9.x)

Scenario

This sample was created as part of a demo showcasing the ease with which a distributed system can be created using the Particular dotnet new Templates.

The scenario for the solution is to keep track of ticket sales at cinemas and feature the film with the most tickets sold for the current month.

sequenceDiagram Customer->>+Cinema (Ticket Sales): Purchase Ticket Cinema (Ticket Sales)->>+Cinema Headquarters: RecordTicketSale Cinema Headquarters-->>-Cinema (Ticket Sales): FeaturedFilmChanged

Running the sample

  1. Run the solution. Two console applications will start.
  2. In the Ticket Sales application, press B or O to sell a ticket for one of the two films.
  3. In the Headquarters application, monitor the logs to see which film has the most sales.
  4. In the Ticket Sales application, monitor the logs to see when the featured film changes.

Follow along

Prerequsities

  1. Visual Studio
  2. Particular.Templates package.
  3. .NET SDK

TicketSales project

The Cinema.TicketSales project provides a console interface to sell tickets for two films. These ticket sales are reported to the Headquarters endpoint by sending a RecordTicketSale message.

Console.WriteLine("B) Sell ticket for Barbie");
Console.WriteLine("O) Sell ticket for Oppenheimer");

while (!cancellationToken.IsCancellationRequested)
{
    if (!Console.KeyAvailable) continue;

    var userInput = Console.ReadKey();
    switch (userInput.Key)
    {
        case ConsoleKey.B:
            await messageSession.Send(new RecordTicketSale
            {
                MonthId = MonthId,
                FilmName = "Barbie"
            }, cancellationToken);
            break;
        case ConsoleKey.O:
            await messageSession.Send(new RecordTicketSale
            {
                MonthId = MonthId,
                FilmName = "Oppenheimer"
            }, cancellationToken);
            break;
        default:
            break;
    }
}

The TicketSales endpoint displays a message when the featured film is changed by the Headquarters endpoint.

Headquarters project

The Cinema.Headquarters project aggregates ticket sales and publishes an event when the featured film for the month changes.

public async Task Handle(RecordTicketSale message, IMessageHandlerContext context)
{
    string featuredFilmBeforeNewSale = GetFeaturedFilm();

    switch (message.FilmName)
    {
        case "Barbie":
            Data.BarbieTicketCount++;
            break;
        case "Oppenheimer":
            Data.OppenheimerTicketCount++;
            break;
        default:
            break;
    }

    string featuredFilmAfterSale = GetFeaturedFilm();

    if (featuredFilmAfterSale != string.Empty
        && featuredFilmBeforeNewSale != featuredFilmAfterSale)
    {
        log.LogInformation($"Featured film changed: {featuredFilmAfterSale}");
        await context.Publish(new FeaturedFilmChanged
        {
            FeaturedFilmName = featuredFilmAfterSale
        });
    }

    log.LogInformation(
        $"Barbie Tickets: {Data.BarbieTicketCount}" +
        $"\nOppenheimer Tickets: {Data.OppenheimerTicketCount}");
}

Messages project

This shared message assembly contains the commands and events that are exchanged between the two endpoints.