Workleap.DomainEventPropagation.Publishing
0.1.0-preview.32
Prefix Reserved
See the version list below for details.
dotnet add package Workleap.DomainEventPropagation.Publishing --version 0.1.0-preview.32
NuGet\Install-Package Workleap.DomainEventPropagation.Publishing -Version 0.1.0-preview.32
<PackageReference Include="Workleap.DomainEventPropagation.Publishing" Version="0.1.0-preview.32" />
paket add Workleap.DomainEventPropagation.Publishing --version 0.1.0-preview.32
#r "nuget: Workleap.DomainEventPropagation.Publishing, 0.1.0-preview.32"
// Install Workleap.DomainEventPropagation.Publishing as a Cake Addin #addin nuget:?package=Workleap.DomainEventPropagation.Publishing&version=0.1.0-preview.32&prerelease // Install Workleap.DomainEventPropagation.Publishing as a Cake Tool #tool nuget:?package=Workleap.DomainEventPropagation.Publishing&version=0.1.0-preview.32&prerelease
Workleap.DomainEventPropagation
Package | Download Link | Description |
---|---|---|
Workleap.DomainEventPropagation.Abstractions | Contains abstractions that are used for publishing and receiving events | |
Workleap.DomainEventPropagation.Publishing | Contains classes to publish events | |
Workleap.DomainEventPropagation.Subscription | Contains classes to subscribe to topics and receive events |
This set of three libraries is meant to 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
Publisher library
Install the package Workleap.DomainEventPropagation.Publishing in your webapi project that wants to send events to Event Grid. Then you can use on of the following methods to register the required services.
// Method 1: Lazily bind the options to a configuration section
services.AddEventPropagationPublisher();
services.AddOptions<EventPropagationPublisherOptions>()
.BindConfiguration(EventPropagationPublisherOptions.SectionName);
// appsetting.json
{
"EventPropagation": {
"TopicName": "<topic_name_to_publish_to>",
"TopicAccessKey": "<keyVault_provided_value>",
"TopicEndpoint": "<azure_topic_uri>"
}
}
// Method 2: Lazily bind the options to a configuration section and use a TokenCredential and RBAC
services.AddEventPropagationPublisher(opt =>
{
opt.TokenCredential = new DefaultAzureCredential();
});
services.AddOptions<EventPropagationPublisherOptions>()
.BindConfiguration(EventPropagationPublisherOptions.SectionName);
// appsetting.json
{
"EventPropagation": {
"TopicName": "<topic_name_to_publish_to>",
"TopicEndpoint": "<azure_topic_uri>"
}
}
// Method 3: Set options values directly in C# using and access key
services.AddEventPropagationPublisher(opt =>
{
opt.TopicName = "<topic_name_to_publish_to>",
opt.TopicEndpoint = "<azure_topic_uri>",
opt.TopicAccessKey = "<provided from keyVault>"
});
// Method 4: Set options values directly in C# using a TokenCredential and RBAC
services.AddEventPropagationPublisher(opt =>
{
opt.TopicName = "<topic_name_to_publish_to>",
opt.TopicEndpoint = "<azure_topic_uri>",
o.TokenCredential = new DefaultAzureCredential())
}
Note that you can use either an access key or a token credentials in order to authenticate with your eventGrid topic but not both.
Now in order to publish a domain event, you first need to define your domain events using the IDomainEvent
interface.
public class ExampleDomainEvent : IDomainEvent
{
public string Id { get; set; }
public DateTime Date { get; set; }
}
Once your domain events are defined, you can use the IEventPropagationClient
interface (via dependency injection).
var domainEvent = new ExampleDomainEvent
{
Id = Guid.NewGuid().ToString(),
Date = DateTime.UtcNow
};
await this._eventPropagationClient.PublishDomainEventAsync(subject: "TestEventPublication", domainEvent);
Subscriber library
Install the package Workleap.DomainEventPropagation.Subscription in your webapi project that wants to receive events from Event Grid. Then you can use on of the following methods to register the required services.
// Method 1: Register only selected domain event handlers
services.AddEventPropagationSubscriber()
.AddDomainEventHandler<ExampleDomainEventHandler>()
.AddDomainEventHandler<SampleDomainEventHandler>();
// Method 2: Register all domain event handlers from an assembly
services
.AddEventPropagationSubscriber()
.AddDomainEventHandlersFromAssembly(Assembly.GetExecutingAssembly());
// Register the webhook endpoint
app.UseEndpoints(endpointBuilder =>
{
endpointBuilder
.AddEventPropagationEndpoint()
.WithAuthorization();
});
You can define your domain event handlers by implementing the IDomainEventHandler<>
interface and then registering them in the service collection as shown above.
public class ExampleDomainEventHandler : IDomainEventHandler<ExampleDomainEvent>
{
public Task HandleDomainEventAsync(ExampleDomainEvent domainEvent, CancellationToken cancellationToken)
{
return Task.CompletedTask;
}
}
Securing your webhook endpoint
It is required to expose an endpoint in order for eventGrid 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:
app.UseEndpoints(endpointBuilder =>
{
endpointBuilder
.AddEventPropagationEndpoint()
.WithAuthorization(); // This here will add an authorize attribute to the endpoint requiring a valid JTW access token.
});
Now that your api endpoint is secure with an authorize attribute, you just need to follow the remaining steps:
- Create a
AzureEventGridSecureWebhookSubscriber
role on your webhook application's app registration. - Grant said role to Microsoft.EventGrid service principal
- Create a webhook EventGrid subscription and specify the TenantId and webhook applicationId
For more details about each of those steps, you can follow this Microsoft documentation.
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.
- DomainEventHandlers must have idempotent behavior (you could execute it multiple times for the same event and the result would always be the same).
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.
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 | Versions 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 | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.0 is compatible. 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 | tizen40 was computed. tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- Azure.Messaging.EventGrid (>= 4.17.0)
- Microsoft.Extensions.Azure (>= 1.6.3)
- Microsoft.Extensions.Configuration (>= 6.0.1)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 6.0.0)
- Microsoft.Extensions.Hosting (>= 6.0.1)
- Microsoft.Extensions.Options.ConfigurationExtensions (>= 6.0.0)
- System.Text.Json (>= 6.0.0)
- Workleap.DomainEventPropagation (>= 0.1.0-preview.32)
- Workleap.DomainEventPropagation.Abstractions (>= 0.1.0-preview.32)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Workleap.DomainEventPropagation.Publishing:
Package | Downloads |
---|---|
Workleap.DomainEventPropagation.Publishing.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 | 34 | 11/29/2024 |
1.1.1-preview.5 | 33 | 11/17/2024 |
1.1.1-preview.4 | 38 | 10/30/2024 |
1.1.1-preview.3 | 42 | 10/28/2024 |
1.1.1-preview.2 | 40 | 10/28/2024 |
1.1.1-preview.1 | 38 | 10/28/2024 |
1.1.0 | 1,768 | 10/9/2024 |
1.0.2-preview.19 | 47 | 10/9/2024 |
1.0.2-preview.18 | 50 | 10/1/2024 |
1.0.2-preview.17 | 47 | 10/1/2024 |
1.0.2-preview.16 | 48 | 10/1/2024 |
1.0.2-preview.15 | 46 | 10/1/2024 |
1.0.2-preview.14 | 41 | 10/1/2024 |
1.0.2-preview.13 | 34 | 9/20/2024 |
1.0.2-preview.12 | 31 | 9/20/2024 |
1.0.2-preview.11 | 47 | 8/27/2024 |
1.0.2-preview.10 | 43 | 8/27/2024 |
1.0.2-preview.9 | 48 | 8/27/2024 |
1.0.2-preview.7 | 43 | 8/27/2024 |
1.0.2-preview.5 | 42 | 8/27/2024 |
1.0.2-preview.4 | 39 | 8/27/2024 |
1.0.2-preview.3 | 42 | 8/27/2024 |
1.0.2-preview.2 | 43 | 8/27/2024 |
1.0.1 | 2,205 | 8/20/2024 |
1.0.1-preview.2 | 65 | 8/20/2024 |
1.0.1-preview.1 | 64 | 8/16/2024 |
1.0.0 | 222 | 8/15/2024 |
0.6.2-preview.2 | 66 | 8/15/2024 |
0.6.2-preview.1 | 61 | 8/15/2024 |
0.6.1 | 2,837 | 8/15/2024 |
0.6.1-preview.5 | 67 | 8/14/2024 |
0.6.1-preview.4 | 61 | 8/14/2024 |
0.6.1-preview.3 | 63 | 8/12/2024 |
0.6.1-preview.2 | 35 | 8/5/2024 |
0.6.1-preview.1 | 46 | 7/26/2024 |
0.6.0 | 493 | 7/18/2024 |
0.5.6-preview.3 | 52 | 7/18/2024 |
0.5.6-preview.2 | 54 | 7/18/2024 |
0.5.6-preview.1 | 52 | 7/18/2024 |
0.5.5-preview.3 | 40 | 7/17/2024 |
0.5.5-preview.2 | 49 | 7/15/2024 |
0.5.4 | 2,862 | 6/19/2024 |
0.5.4-preview.5 | 52 | 6/17/2024 |
0.5.4-preview.4 | 50 | 6/17/2024 |
0.5.4-preview.3 | 54 | 6/14/2024 |
0.5.4-preview.2 | 50 | 6/14/2024 |
0.5.4-preview.1 | 48 | 6/13/2024 |
0.5.3 | 1,446 | 5/21/2024 |
0.5.3-preview.1 | 65 | 5/10/2024 |
0.5.2 | 4,935 | 4/17/2024 |
0.5.2-preview.2 | 74 | 4/12/2024 |
0.5.2-preview.1 | 179 | 4/8/2024 |
0.5.1 | 1,135 | 4/8/2024 |
0.5.1-preview.1 | 64 | 4/8/2024 |
0.4.1-preview.10 | 71 | 4/8/2024 |
0.4.1-preview.9 | 61 | 3/28/2024 |
0.4.1-preview.8 | 63 | 3/26/2024 |
0.4.1-preview.7 | 73 | 3/19/2024 |
0.4.1-preview.6 | 58 | 3/18/2024 |
0.4.1-preview.5 | 53 | 3/8/2024 |
0.4.1-preview.4 | 60 | 3/7/2024 |
0.4.1-preview.3 | 62 | 3/4/2024 |
0.4.1-preview.2 | 57 | 3/4/2024 |
0.4.1-preview.1 | 58 | 2/29/2024 |
0.4.0 | 4,646 | 2/27/2024 |
0.3.1-preview.6 | 66 | 2/26/2024 |
0.3.1-preview.5 | 56 | 2/26/2024 |
0.3.1-preview.4 | 65 | 2/23/2024 |
0.3.1-preview.3 | 65 | 2/16/2024 |
0.3.1-preview.2 | 76 | 2/6/2024 |
0.3.1-preview.1 | 337 | 2/6/2024 |
0.3.0 | 2,091 | 1/26/2024 |
0.2.1-preview.24 | 57 | 1/23/2024 |
0.2.1-preview.23 | 58 | 1/22/2024 |
0.2.1-preview.22 | 63 | 1/12/2024 |
0.2.1-preview.21 | 59 | 1/12/2024 |
0.2.1-preview.20 | 62 | 1/12/2024 |
0.2.1-preview.18 | 76 | 12/18/2023 |
0.2.1-preview.17 | 95 | 12/7/2023 |
0.2.1-preview.16 | 111 | 11/17/2023 |
0.2.1-preview.15 | 96 | 11/13/2023 |
0.2.1-preview.14 | 65 | 11/13/2023 |
0.2.1-preview.13 | 76 | 11/7/2023 |
0.2.1-preview.11 | 136 | 10/24/2023 |
0.2.1-preview.10 | 84 | 10/20/2023 |
0.2.1-preview.8 | 85 | 10/17/2023 |
0.2.1-preview.7 | 86 | 10/13/2023 |
0.2.1-preview.6 | 75 | 10/2/2023 |
0.2.1-preview.5 | 79 | 9/26/2023 |
0.2.1-preview.4 | 66 | 9/21/2023 |
0.2.1-preview.3 | 71 | 9/21/2023 |
0.2.1-preview.2 | 81 | 9/21/2023 |
0.2.1-preview.1 | 76 | 9/21/2023 |
0.2.0 | 8,942 | 9/21/2023 |
0.1.1-preview.6 | 80 | 9/20/2023 |
0.1.1-preview.5 | 73 | 9/20/2023 |
0.1.1-preview.4 | 88 | 9/19/2023 |
0.1.1-preview.3 | 93 | 9/13/2023 |
0.1.1-preview.2 | 83 | 9/13/2023 |
0.1.1-preview.1 | 92 | 9/11/2023 |
0.1.0 | 220 | 9/7/2023 |
0.1.0-preview.33 | 86 | 9/7/2023 |
0.1.0-preview.32 | 85 | 8/25/2023 |
0.1.0-preview.31 | 83 | 8/22/2023 |
0.1.0-preview.30 | 75 | 8/18/2023 |
0.1.0-preview.29 | 84 | 8/16/2023 |
0.1.0-preview.28 | 80 | 8/16/2023 |
0.1.0-preview.27 | 81 | 8/15/2023 |
0.1.0-preview.26 | 79 | 8/14/2023 |
0.1.0-preview.24 | 90 | 8/10/2023 |
0.1.0-preview.23 | 99 | 8/9/2023 |
0.1.0-preview.22 | 91 | 8/4/2023 |
0.1.0-preview.21 | 86 | 8/4/2023 |
0.1.0-preview.20 | 86 | 8/3/2023 |
0.1.0-preview.19 | 89 | 8/1/2023 |
0.1.0-preview.17 | 95 | 8/1/2023 |