Find a file
Craig Fowler b583c7f1a9
Resolves #485 - Add PurgeVariables functionality (#654)
* Trivial - Add VS Code workspace

* Trivial - Add VSCode build task & extra ignore

On GNU/Linux, auto-generated .directory
files should be ignored.

* WIP #485 - Boilerplate for unit test project

* WIP #485 - Add test coverage (Remove/RemoveAll)

* WIP #485 - Implement RemoveAll

* Remove redundant logic, covered by IDictionary

Per the following, the contract for a generic IDictionary,
the Remove method already deals with non-existent keys.

  https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.idictionary-2.remove?view=net-5.0#System_Collections_Generic_IDictionary_2_Remove__0_

* Resolve #485 - Add PurgeVariables methods

These are convenience methods upon ActivityExecutionContext
and WorkflowExecutionContext, consistent with their current APIs.

Also in this commit are tests for those simple methods.
There's a bit of test-scaffold as well included, such as:
* Autofixture Xunit2 integration
* New project for unit tests
* Customize attribute for avoiding crashes on Autofixture recursion
* Reusable specimen builder for creating IServiceProvider which
  resolves services from Autofixture
* Custonize attribute for a parameter to use that ^^ specimen builder
2021-02-24 14:29:03 +01:00
.vscode Resolves #485 - Add PurgeVariables functionality (#654) 2021-02-24 14:29:03 +01:00
design Add AI file 2020-11-12 21:49:07 +01:00
doc Add logo 2020-11-15 22:25:58 +01:00
src Resolves #485 - Add PurgeVariables functionality (#654) 2021-02-24 14:29:03 +01:00
test Resolves #485 - Add PurgeVariables functionality (#654) 2021-02-24 14:29:03 +01:00
.dockerignore Add Dockerfile and docker-compose (#186) 2019-11-19 19:25:56 +01:00
.editorconfig Add source file + line number to execution log. (#571) 2021-01-14 21:45:28 +01:00
.gitattributes Add .gitattributes 2020-03-28 22:38:52 +01:00
.gitignore Resolves #485 - Add PurgeVariables functionality (#654) 2021-02-24 14:29:03 +01:00
appveyor.yml Update Node version 2021-02-13 11:22:07 +01:00
common.props Remove PackageVersion (to be supplied by AppVeyor) 2020-12-17 16:19:06 +01:00
configureawait.props Enhance project structure (#524) 2020-12-16 10:31:02 +01:00
CONTRIBUTING.md edit contributing.md (#549) 2021-01-04 10:49:58 +01:00
docker-compose.yaml Add Rebus service bus providers for Azure Service Bus and RabbitMQ 2020-11-22 13:05:34 +01:00
Dockerfile Add Dockerfile and docker-compose (#186) 2019-11-19 19:25:56 +01:00
Elsa.code-workspace Resolves #485 - Add PurgeVariables functionality (#654) 2021-02-24 14:29:03 +01:00
Elsa.sln Resolves #485 - Add PurgeVariables functionality (#654) 2021-02-24 14:29:03 +01:00
Elsa.sln.DotSettings EF Core Persistence Provider (#557) 2021-01-07 13:01:19 +01:00
global.disabled.json Improve specifications and YesSQL implementation (#529) 2020-12-20 12:12:32 +01:00
LICENSE Update LICENSE 2020-04-02 20:06:28 +02:00
Nuget.Config Implement activity property setters 2020-10-03 12:48:25 +02:00
README.md Update README.md 2021-02-11 10:22:30 +01:00

Elsa Logo

Elsa Workflows

Nuget (with prereleases) MyGet (with prereleases) Build status Gitter Stack Overflow questions Docker Pulls

Elsa Core is a workflows library that enables workflow execution in any .NET Core application. Workflows can be defined not only using code but also as JSON, YAML or XML.

Elsa 2 Preview

Get Started

Follow the Getting Started instructions on the Elsa Workflows documentation site.

Roadmap

Version 1.0

  • Workflow Invoker
  • Long-running Workflows
  • Workflows as code
  • Workflows as data
  • Correlation
  • Persistence: CosmosDB, Entity Framework Core, MongoDB, YesSQL
  • HTML5 Workflow Designer Web Component
  • ASP.NET Core Workflow Dashboard
  • JavaScript Expressions
  • Liquid Expressions
  • Primitive Activities
  • Control Flow Activities
  • Workflow Activities
  • Timer Activities
  • HTTP Activities
  • Email Activities

Version 2.0

  • Composite Activities API
  • Service Bus Messaging
  • Workflow Host REST API
  • Workflow Server
  • Distributed Hosting Support (support for multi-node environments)
  • Lucene Indexing
  • New Workflow Designer + Dashboard
  • Generic Command & Event Activities
  • Job Activities (simplify kicking off a background process while the workflow sleeps & gets resumed once job finishes)

Version 3.0

  • Composite Activity Definitions (with designer support)
  • Localization Support
  • State Machines
  • Sagas

Workflow Designer

Workflows can be visually designed using the Elsa Designer, a reusable & extensible HTML5 web component built with StencilJS. To manage workflow definitions and instances, Elsa comes with a reusable Razor Class Library that provides a dashboard application in the form of an MVC area that you can include in your own ASP.NET Core application.

Programmatic Workflows

Workflows can be created programmatically and then executed using IWorkflowRunner or scheduled for execution using IWorkflowQueue.

Hello World

The following code snippet demonstrates creating a workflow with two WriteLine activities from code and then invoking it:


// Define a strongly-typed workflow.
public class HelloWorldWorkflow : IWorkflow
{
    public void Build(IWorkflowBuilder builder)
    {
        builder
            .WriteLine("Hello World!")
            .WriteLine("Goodbye cruel world...");
    }
}

// Setup a service collection.
var services = new ServiceCollection()
    .AddElsa()
    .AddConsoleActivities()
    .AddWorkflows<HelloWorldWorkflow>()
    .BuildServiceProvider();

// Run startup actions (not needed when registering Elsa with a Host).
var startupRunner = services.GetRequiredService<IStartupRunner>();
await startupRunner.StartupAsync();

// Get a workflow runner.
var workflowRunner = services.GetService<IWorkflowRunner>();

// Run the workflow.
await workflowRunner.RunWorkflowAsync<HelloWorld>();

// Output:
// /> Hello World!
// /> Goodbye cruel world...

Declarative Workflows

Instead of writing C# code to define a workflow, Elsa also supports reading and writing declarative workflows from the database as well as from JSON formats. The following is a small example that constructs a workflow using a generic set of workflow and activity models, describing the workflow. This models is then serialized to JSON and deserialized back into the model

// Create a service container with Elsa services.
var services = new ServiceCollection()
    .AddElsa()


    // For production use.
    .UseYesSqlPersistence()
    
    // Or use any of the other supported persistence providers such as EF Core or MongoDB:
    // .UseEntityFrameworkPersistence(ef => ef.UseSqlite())
    // .UseMongoDbPersistence()

    .BuildServiceProvider();

// Run startup actions (not needed when registering Elsa with a Host).
var startupRunner = services.GetRequiredService<IStartupRunner>();
await startupRunner.StartupAsync();

// Define a workflow.
var workflowDefinition = new WorkflowDefinition
{
    WorkflowDefinitionId = "SampleWorkflow",
    WorkflowDefinitionVersionId = "1", 
    Version = 1,
    IsPublished = true,
    IsLatest = true,
    IsEnabled = true,
    PersistenceBehavior = WorkflowPersistenceBehavior.Suspended,
    Activities = new[]
    {
        new ActivityDefinition
        {
            ActivityId = "activity-1",
            Type = nameof(WriteLine),
            Properties = new ActivityDefinitionProperties
            {
                [nameof(WriteLine.Text)] = new ActivityDefinitionPropertyValue
                {
                    Syntax = "Literal",
                    Expression = "Hello World!",
                    Type = typeof(string)
                }
            }
        }, 
    }
};

// Serialize workflow definition to JSON.
var serializer = services.GetRequiredService<IContentSerializer>();
var json = serializer.Serialize(workflowDefinition);

Console.WriteLine(json);

// Deserialize workflow definition from JSON.
var deserializedWorkflowDefinition = serializer.Deserialize<WorkflowDefinition>(json);

// Materialize workflow.
var materializer = services.GetRequiredService<IWorkflowBlueprintMaterializer>();
var workflowBlueprint = materializer.CreateWorkflowBlueprint(deserializedWorkflowDefinition);

// Execute workflow.
var workflowRunner = services.GetRequiredService<IWorkflowRunner>();
await workflowRunner.RunWorkflowAsync(workflowBlueprint);

Persistence

Elsa abstractes away data access, which means you can use any persistence provider you prefer.

Long Running Workflows

Elsa has native support for long-running workflows. As soon as a workflow is halted because of some blocking activity, the workflow is persisted. When the appropriate event occurs, the workflow is loaded from the store and resumed.

Why Elsa Workflows?

One of the main goals of Elsa is to enable workflows in any .NET application with minimum effort and maximum extensibility. This means that it should be easy to integrate workflow capabilities into your own application.

What about Azure Logic Apps?

As powerful and as complete Azure Logic Apps is, it's available only as a managed service in Azure. Elsa on the other hand allows you to host it not only on Azure, but on any cloud provider that supports .NET Core. And of course you can host it on-premise.

Although you can implement long-running workflows with Logic Apps, you would typically do so with splitting your workflow with multiple Logic Apps where one workflow invokes the other. This can make the logic flow a bit hard to follow. with Elsa, you simply add triggers anywhere in the workflow, making it easier to have a complete view of your application logic. And if you want, you can still invoke other workflows form one workflow.

What about Windows Workflow Foundation?

I've always liked Windows Workflow Foundation, but unfortunately development appears to have halted. Although there's an effort being made to port WF to .NET Standard, there are a few reasons I prefer Elsa:

  • Elsa intrinsically supports triggering events that starts new workflows and resumes halted workflow instances in an easy to use manner. E.g. workflowHost.TriggerWorkflowAsync("HttpRequestTrigger");" will start and resume all workflows that either start with or are halted on the HttpRequestTrigger.
  • Elsa has a web-based workflow designer. I once worked on a project for a customer that was building a huge SaaS platform. One of the requirements was to provide a workflow engine and a web-based editor. Although there are commercial workflow libraries and editors out there, the business model required open-source software. We used WF and the re-hosted Workflow Designer. It worked, but it wasn't great.

What about Orchard Workflows?

Both Orchard and Orchard Core ship with a powerful workflows module, and both are awesome. In fact, Elsa Workflows is taken & adapted from Orchard Core's Workflows module. Elsa uses a similar model, but there are some differences:

  • Elsa Workflows is completely decoupled from web, whereas Orchard Core Workflows is coupled to not only the web, but also the Orchard Core Framework itself.
  • Elsa Workflows can execute in any .NET Core application without taking a dependency on any Orchard Core packages.

Features

TODO

How to use Elsa

TODO

Setting up a Workflow Designer ASP.NET Core Application

TODO: describe all the steps to add packages and register services.

Setting up a Workflow Host .NET Application

TODO: describe all the steps to add packages and register services.

Building & Running Elsa Workflows Dashboard

TODO

Code of Conduct

This project has adopted the code of conduct defined by the Contributor Covenant to clarify expected behavior in our community. For more information see the .NET Foundation Code of Conduct.

.NET Foundation

This project is supported by the .NET Foundation.