Workleap.DomainEventPropagation.Subscription 0.3.0

Prefix Reserved
There is a newer version of this package available.
See the version list below for details.
dotnet add package Workleap.DomainEventPropagation.Subscription --version 0.3.0                
NuGet\Install-Package Workleap.DomainEventPropagation.Subscription -Version 0.3.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="Workleap.DomainEventPropagation.Subscription" Version="0.3.0" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Workleap.DomainEventPropagation.Subscription --version 0.3.0                
#r "nuget: Workleap.DomainEventPropagation.Subscription, 0.3.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 Workleap.DomainEventPropagation.Subscription as a Cake Addin
#addin nuget:?package=Workleap.DomainEventPropagation.Subscription&version=0.3.0

// Install Workleap.DomainEventPropagation.Subscription as a Cake Tool
#tool nuget:?package=Workleap.DomainEventPropagation.Subscription&version=0.3.0                

Workleap.DomainEventPropagation

build

Package Download Link Description
Workleap.DomainEventPropagation.Abstractions nuget Contains abstractions that are used for publishing and receiving events
Workleap.DomainEventPropagation.Publishing nuget Contains types used to publish events from any kind of .NET application
Workleap.DomainEventPropagation.Publishing.ApplicationInsights nuget Adds Application Insights distributed tracing when publishing events
Workleap.DomainEventPropagation.Subscription nuget Contains types for an ASP.NET Core app to subscribe to Event Grid topics and receive events
Workleap.DomainEventPropagation.Subscription.ApplicationInsights nuget Adds Application Insights distributed tracing when receiving events

These libraries must be used in conjunction with Azure Event Grid in order to publish and receive domain events. It is meant to be used in a multi-services architecture where each service is responsible for its own data and publishes events to notify other services of changes.

Getting started

Publish domain events

Install the package Workleap.DomainEventPropagation.Publishing in your .NET project that wants to send events to an Event Grid topic. Then, you can use one of the following methods to register the required services.

// Method 1: Automatically bind the options to a well-known configuration section
services.AddEventPropagationPublisher();

// appsetting.json (or any other configuration source)
{
  "EventPropagation": {
    "Publisher": {
      "TopicEndpoint": "<azure_topic_uri>",
      "TopicAccessKey": "<secret_value>"
    }
  }
}

// Method 2: Automatically bind the options to a well-known configuration section with Azure Identity (RBAC)
services.AddEventPropagationPublisher(options =>
{
    options.TokenCredential = new DefaultAzureCredential();
});

// appsetting.json (or any other configuration source)
{
  "EventPropagation": {
    "Publisher": {
      "TopicEndpoint": "<azure_topic_uri>"
    }
  }
}

// Method 3: Set options values directly in C#
services.AddEventPropagationPublisher(options =>
{
    options.TopicEndpoint = "<azure_topic_uri>";

    // Using an access key        
    options.TopicAccessKey = "<secret_value>";
    
    // Using Azure Identity (RBAC)
    options.TokenCredential = new DefaultAzureCredential();
});

Note that you can use either an access key or a token credential in order to authenticate to your eventGrid topic, not both.

Then, in order to publish a domain event, you first need to define your domain events using the IDomainEvent interface. Decorate the domain event with the [DomainEvent] attribute, specifying a unique event name.

[DomainEvent("example")]
public class ExampleDomainEvent : IDomainEvent
{
    public string Id { get; set; }
}

Once your domain events are defined, you can inject and use the IEventPropagationClient service.

var domainEvent = new ExampleDomainEvent
{
    Id = Guid.NewGuid().ToString()
};

await this._eventPropagationClient.PublishDomainEventAsync(domainEvent, CancellationToken.None);

Subscribe to domain events

Install the package Workleap.DomainEventPropagation.Subscription in your ASP.NET Core project that wants to receive events from Event Grid topics.

You can define your domain event handlers by implementing the IDomainEventHandler<> interface and then registering them in the service collection later.

public class ExampleDomainEventHandler : IDomainEventHandler<ExampleDomainEvent>
{
    public Task HandleDomainEventAsync(ExampleDomainEvent domainEvent, CancellationToken cancellationToken)
    {
        // Do something with the domain event
        return Task.CompletedTask;
    }
}

Then, you can use on of the following methods to register the required services and map the webhook endpoint.

// Method 1: Register only selected domain event handlers
services.AddEventPropagationSubscriber()
    .AddDomainEventHandler<ExampleDomainEvent, ExampleDomainEventHandler>()
    .AddDomainEventHandler<OtherDomainEvent, OtherDomainEventHandler>();

// Method 2: Register all domain event handlers from a given assembly
services.AddEventPropagationSubscriber()
    .AddDomainEventHandlers(Assembly.GetExecutingAssembly());

// Register the webhook endpoint in your ASP.NET Core app (startup-based approach)
app.UseEndpoints(builder =>
{
    builder.MapEventPropagationEndpoint();
});

// Register the webhook endpoint in your ASP.NET Core app (minimal APIs approach)
app.MapEventPropagationEndpoint();
Securing the webhook endpoint

It is required to expose an ASP.NET Core endpoint in order for Event Grid topics to be able to push events. By default, the registered endpoint will allow anonymous access, but it is possible to secure it as shown below:

// "RequireAuthorization" is a built-in ASP.NET Core method so you can specify any authorization policy you want
app.MapEventPropagationEndpoint().RequireAuthorization();

Now, follow this Microsoft documentation to continue the configuration.

Additional notes

  • You may only define one domain event handler per domain event you wish to handle. If you would require more, use the single allowed domain event handler as a facade for multiple operations.
  • Domain event handlers must have idempotent behavior (you could execute it multiple times for the same event and the result would always be the same).
  • If your domain event types and handlers are in dedicated assemblies, you can reference the Workleap.DomainEventPropagation.Abstractions packages in order to avoid a dependency on third-parties like Azure and Microsoft extensions.

Building, releasing and versioning

The project can be built by running Build.ps1. It uses Microsoft.CodeAnalysis.PublicApiAnalyzers to help detect public API breaking changes. Use the built-in roslyn analyzer to ensure that public APIs are declared in PublicAPI.Shipped.txt, and obsolete public APIs in PublicAPI.Unshipped.txt.

A new preview NuGet package is automatically published on any new commit on the main branch. This means that by completing a pull request, you automatically get a new NuGet package.

When you are ready to officially release a stable NuGet package by following the SemVer guidelines, simply manually create a tag with the format x.y.z. This will automatically create and publish a NuGet package for this version.

Included Roslyn analyzers

Rule ID Category Severity Description
WLDEP01 Usage Warning Use DomainEvent attribute on event
WLDEP02 Usage Warning Use unique event name in attribute

To modify the severity of one of these diagnostic rules, you can use a .editorconfig file. For example:

## Disable analyzer for test files
[**Tests*/**.cs]
dotnet_diagnostic.WLDEP01.severity = none
dotnet_diagnostic.WLDEP02.severity = none

To learn more about configuring or suppressing code analysis warnings, refer to this documentation.

License

Copyright © 2023, Workleap This code is licensed under the Apache License, Version 2.0. You may obtain a copy of this license at https://github.com/gsoft-inc/gsoft-license/blob/master/LICENSE.

Product Compatible and additional computed target framework versions.
.NET net6.0 is compatible.  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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on Workleap.DomainEventPropagation.Subscription:

Package Downloads
Workleap.DomainEventPropagation.Subscription.ApplicationInsights

Propagate domain events with Azure

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.1.1-preview.6 23 11/29/2024
1.1.1-preview.5 34 11/17/2024
1.1.1-preview.4 40 10/30/2024
1.1.1-preview.3 40 10/28/2024
1.1.1-preview.2 39 10/28/2024
1.1.1-preview.1 38 10/28/2024
1.1.0 2,178 10/9/2024
1.0.2-preview.19 43 10/9/2024
1.0.2-preview.18 52 10/1/2024
1.0.2-preview.17 48 10/1/2024
1.0.2-preview.16 49 10/1/2024
1.0.2-preview.15 48 10/1/2024
1.0.2-preview.14 63 10/1/2024
1.0.2-preview.13 37 9/20/2024
1.0.2-preview.12 30 9/20/2024
1.0.2-preview.11 47 8/27/2024
1.0.2-preview.10 48 8/27/2024
1.0.2-preview.9 46 8/27/2024
1.0.2-preview.7 42 8/27/2024
1.0.2-preview.5 41 8/27/2024
1.0.2-preview.4 42 8/27/2024
1.0.2-preview.3 42 8/27/2024
1.0.2-preview.2 45 8/27/2024
1.0.1 1,573 8/20/2024
1.0.1-preview.2 67 8/20/2024
1.0.1-preview.1 68 8/16/2024
1.0.0 277 8/15/2024
0.6.2-preview.2 77 8/15/2024
0.6.2-preview.1 62 8/15/2024
0.6.1 4,454 8/15/2024
0.6.1-preview.5 67 8/14/2024
0.6.1-preview.4 67 8/14/2024
0.6.1-preview.3 60 8/12/2024
0.6.1-preview.2 36 8/5/2024
0.6.1-preview.1 44 7/26/2024
0.6.0 1,691 7/18/2024
0.5.6-preview.3 57 7/18/2024
0.5.6-preview.2 52 7/18/2024
0.5.6-preview.1 53 7/18/2024
0.5.5-preview.3 38 7/17/2024
0.5.5-preview.2 53 7/15/2024
0.5.4 2,090 6/19/2024
0.5.4-preview.5 52 6/17/2024
0.5.4-preview.4 51 6/17/2024
0.5.4-preview.3 51 6/14/2024
0.5.4-preview.2 49 6/14/2024
0.5.4-preview.1 48 6/13/2024
0.5.3 4,140 5/21/2024
0.5.3-preview.1 66 5/10/2024
0.5.2 10,421 4/17/2024
0.5.2-preview.2 71 4/12/2024
0.5.2-preview.1 57 4/8/2024
0.5.1 1,572 4/8/2024
0.5.1-preview.1 59 4/8/2024
0.4.1-preview.10 69 4/8/2024
0.4.1-preview.9 57 3/28/2024
0.4.1-preview.8 62 3/26/2024
0.4.1-preview.7 65 3/19/2024
0.4.1-preview.6 55 3/18/2024
0.4.1-preview.5 63 3/8/2024
0.4.1-preview.4 59 3/7/2024
0.4.1-preview.3 68 3/4/2024
0.4.1-preview.2 62 3/4/2024
0.4.1-preview.1 64 2/29/2024
0.4.0 14,475 2/27/2024
0.3.1-preview.6 67 2/26/2024
0.3.1-preview.5 63 2/26/2024
0.3.1-preview.4 66 2/23/2024
0.3.1-preview.3 64 2/16/2024
0.3.1-preview.2 73 2/6/2024
0.3.1-preview.1 58 2/6/2024
0.3.0 8,483 1/26/2024
0.2.1-preview.24 65 1/23/2024
0.2.1-preview.23 56 1/22/2024
0.2.1-preview.22 71 1/12/2024
0.2.1-preview.21 58 1/12/2024
0.2.1-preview.20 56 1/12/2024
0.2.1-preview.18 80 12/18/2023
0.2.1-preview.17 104 12/7/2023
0.2.1-preview.16 114 11/17/2023
0.2.1-preview.15 93 11/13/2023
0.2.1-preview.14 74 11/13/2023
0.2.1-preview.13 75 11/7/2023
0.2.1-preview.11 138 10/24/2023
0.2.1-preview.10 81 10/20/2023
0.2.1-preview.8 85 10/17/2023
0.2.1-preview.7 78 10/13/2023
0.2.1-preview.6 85 10/2/2023
0.2.1-preview.5 77 9/26/2023
0.2.1-preview.4 69 9/21/2023
0.2.1-preview.3 80 9/21/2023
0.2.1-preview.2 71 9/21/2023
0.2.1-preview.1 72 9/21/2023
0.2.0 12,708 9/21/2023
0.1.1-preview.6 84 9/20/2023
0.1.1-preview.5 73 9/20/2023
0.1.1-preview.4 77 9/19/2023
0.1.1-preview.3 94 9/13/2023
0.1.1-preview.2 85 9/13/2023
0.1.1-preview.1 95 9/11/2023
0.1.0 184 9/7/2023
0.1.0-preview.33 92 9/7/2023
0.1.0-preview.32 81 8/25/2023
0.1.0-preview.31 77 8/22/2023
0.1.0-preview.30 71 8/18/2023
0.1.0-preview.29 82 8/16/2023
0.1.0-preview.28 75 8/16/2023
0.1.0-preview.27 90 8/15/2023
0.1.0-preview.26 80 8/14/2023
0.1.0-preview.24 97 8/10/2023
0.1.0-preview.23 97 8/9/2023
0.1.0-preview.22 94 8/4/2023
0.1.0-preview.21 88 8/4/2023
0.1.0-preview.20 90 8/3/2023
0.1.0-preview.19 92 8/1/2023
0.1.0-preview.17 88 8/1/2023