This project is provided to the larger open-source community by Innovian.
This solution implements an aspect using Metalama targeting .NET 8 that provides a utility intended for use with Dapr Workflows. When using .NET, the expected approach is to register the various Workflow and Workflow Activities in the DI registration process, but this can be cumbersome and time-consuming to maintain, especially in projects surfacing a great many such types. Rather than rely on a reflection-based approach to locate each of these types during startup, this aspect provides the same capability but at compilation time, ensuring that all Workflow and Workflow Activities in the project are properly registered in DI as expected, limiting the potential for developer error and bugs that show up online at runtime.
The attribute performs the following:
- Introduces a new class into the project with the namespace
<Program namespace>.DaprUtilities
where<Program namespace>
is the namespace used in your Program.cs file within a public, partial, static class calledDaprRegistrationHelper
. - Introduces a new method into this type named "DaprRegistrationHelper".
- When provided with a list of Workflows and Workflow Activities from the Fabric, this will introduce a registration for each into the introduced method.
While a package is available on NuGet for the attribute itself, it's intended that the target developer only utilize the Fabric to apply this attribute. This is because it's the Fabric that locates the
Workflow and Workfow Activity types in the project and compiles them for the attribute to build the registration method in the target type. Applying the attribute directly to a DaprRegistrationHelper
class
will only introduce the RegisterAllEntities
method, but will not actually register any of the Workflows or Workflow Activities.
The Fabric identifies Workflows by looking for those types in the project that implement an abstract base type called "Workflow" and identifies Workflow Activities by looking for those types in the project that implement an abstract base type called "WorkflowActivity".
The team at Postsharp were kind enough to grant this project an open source license meaning that this namespace can be built with any number of aspects without a Metalama license. However, you will a Metalama license to use this in your own project. Their free license allows up to 3 aspects at no cost. I've purchased a commercial license for their software for use at my own company and if you similarly find that this aspects adds sufficient value to your own work, I encourage you to purchase licenses for your own team.
Using the .NET CLI tools:
dotnet add package Innovian.Dapr.Workflow.RegistrationAspect
Using the Package Manager Console:
Install-Package Innovian.Dapr.Workflow.RegistrationAspect
From within Visual Studio:
- Open the Solution Explorer.
- Right-click on the project within your solution you wish to add the attribute to.
- Click on "Manage NuGet Packages...".
- Click on the "Browse" tab and search for "Innovian.Dapr.Workflow.RegistrationAspect".
- Click on the "Innovian.Dapr.Workflow.RegistrationAspect" package, select the appropriate version in the right-tab and click Install.
No additional effort is necessary beyond installation of the Innovian.Dapr.Workflow.RegistrationAspect
package on the project to configure the fabric or the applied aspect. It will automatically identify all each of the
Workflow and Workflow Activities in the project, introduce the static type DaprRegistrationHelper
and a static method called RegisterAllEntities
. Because it's not yet possible to modify statements within a method at this time, registration is
left as an exercise to the use of both the Dapr Workflow client and the Dapr Workflows (via the introduced static method).
For example, let's say you've got a simple Program.cs and you want to register everything for Dapr. You'd start off with the following:
using Microsoft.AspNetCore.Builder;
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/", () => "Hello World!");
app.Run();
And to register your Dapr workflows, simply update to reflect the following (note your namespace will likely vary based on your own Program.cs namespace):
using Dapr.Workflow;
using DaprUtilities;
using Microsoft.AspNetCore.Builder;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDaprWorkflowClient();
builder.Services.AddDaprWorkflow(DaprRegistrationHelper.RegisterAllEntities);
var app = builder.Build();
app.MapGet("/", () => "Hello World!");
app.Run();
The builder.Services.AddDaprWorkflowClient();
statement is required for typical Dapr Workflow client registration and is not impacted by this attribute, but is included for completeness.
However, the following line builder.Services.AddDaprWorkflow(DaprRegistrationHelper.RegisterAllEntities);
will not work until the aspect has been applied to your project as neither
the DaprRegistrationHelper
static class nor its internal method will necessarily already exist in your project. Rather, these will be introduced by the fabric and aspect and are
invoked precisely as you see above as though you'd written them yourself. And that's it!
Happy coding!