elsa-workflows / elsa-workflows/elsa-core
Activity description not displayed when Activity created using IActivityTypeProvider
- Dominant language
- C#
- Stars
- 7.9k
- Forks
- 1.5k
- Avg merge
- 15h 22m
- Merged PRs (30d)
- 114
Description
Connected with my question in #875.
I've finished writing my first shot at creating `Activity` using `IActivityTypeProvider`, code provided below.
It displays in designer and executes OK :).
The only problem I still have is that the Activity description, `Test activity description`, is not displayed in the designer.

Could you please help if I did something wrong, or....?
In addition if you see anything in my solution that I should not be doing, please shout :)
Thank you.
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Elsa;
using Elsa.ActivityResults;
using Elsa.Design;
using Elsa.Exceptions;
using Elsa.Expressions;
using Elsa.Metadata;
using Elsa.Services;
using Elsa.Services.Models;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
namespace Test
{
public interface IDictionaryActivity : IActivity
{
public IDictionary Properties { get; }
}
public class TestActivity : Activity, IDictionaryActivity
{
public IDictionary Properties { get; } = new Dictionary();
private readonly ILogger _logger;
public TestActivity(ILogger logger)
{
_logger = logger;
_logger.LogInformation("Test activity constructor");
}
protected override async ValueTask OnExecuteAsync(ActivityExecutionContext context)
{
_logger.LogInformation("Test activity OnExecuteAsync");
_logger.LogDebug(GetPropertyString("FirstProperty"));
_logger.LogDebug(GetPropertyString("SecondProperty"));
_logger.LogDebug(GetPropertyString("ThirdProperty"));
_logger.LogDebug(GetPropertyString("FourthProperty"));
return Done();
}
private string GetPropertyString(string name)
{
object ret;
if (!Properties.TryGetValue(name, out ret))
ret = "missing";
return $"{name} = {(ret == null ? "null" : ret.ToString())}";
}
}
public class TestActivityTypeProvider : IActivityTypeProvider
{
public ValueTask> GetActivityTypesAsync(CancellationToken cancellationToken = default)
{
return new(new ActivityType[] { CreateTestActivityType() });
}
private ActivityType CreateTestActivityType()
{
List properties = new List();
properties.Add(
new ActivityPropertyDescriptor(
"FirstProperty",
typeof(string), // property type
ActivityPropertyUIHints.Dropdown, // property UI hint
"First Property Label",
"First Property description and a very long one",
new[] { "value1", "value2", "value3" }, // possible property values
null, // cathegory
"value2", // default value
SyntaxNames.Literal, // default syntax
new[] { SyntaxNames.JavaScript, SyntaxNames.Liquid }) // allowed syntaxes
);
properties.Add(
new ActivityPropertyDescriptor(
"SecondProperty",
typeof(HashSet), // property type
ActivityPropertyUIHints.CheckList, // property UI hint
"First Property Label",
"First Property description and a very long one",
new[] { "value9", "value8", "value7" }, // possible property values
null, // cathegory
"value8", // default value
SyntaxNames.Json, // default syntax
new[] { SyntaxNames.Json, SyntaxNames.JavaScript, SyntaxNames.Liquid }) // allowed syntaxes
);
properties.Add(
new ActivityPropertyDescriptor(
"ThirdProperty",
typeof(string), // property type
ActivityPropertyUIHints.Dropdown, // property UI hint
"Third Property Label",
"Third Property description and a very long one",
new[] { new SelectListItem("name1", "value1"), new SelectListItem("name2", "value2"), new SelectListItem("name3", "value3") }, // possible property values
null, // cathegory
"value3", // default value
SyntaxNames.Literal, // default syntax
new[] { SyntaxNames.JavaScript, SyntaxNames.Liquid }) // allowed syntaxes
);
properties.Add(
new ActivityPropertyDescriptor(
"FourthProperty",
typeof(string[]), // property type
ActivityPropertyUIHints.CheckList, // property UI hint
"Fourth Property Label",
"Fourth Property description and a very long one",
new[] { new SelectListItem("name9", "value9"), new SelectListItem("name8", "value8"), new SelectListItem("name7", "value7") }, // possible property values
null, // cathegory
"value9", // default value
SyntaxNames.Json, // default syntax
new[] { SyntaxNames.Json, SyntaxNames.JavaScript, SyntaxNames.Liquid }) // allowed syntaxes
);
var descriptor = new ActivityDescriptor
{
Type = typeof(TestActivity).FullName,
Category = "Test",
Traits = ActivityTraits.Action,
DisplayName = "Test Activity",
Outcomes = new[] { OutcomeNames.Done, OutcomeNames.False },
Properties = properties.ToArray()
};
Type activityType = typeof(TestActivity);
return new ActivityType
{
TypeName = descriptor.Type,
Type = activityType,
Description = "Test activity description",
DisplayName = descriptor.DisplayName,
Describe = () => descriptor,
ActivateAsync = async context =>
{
return await ActivateActivityAsync(context, activityType);
},
CanExecuteAsync = async context =>
{
var instance = await ActivateActivityAsync(context, activityType);
return await instance.CanExecuteAsync(context);
},
ExecuteAsync = async context =>
{
var instance = await ActivateActivityAsync(context, activityType);
return await instance.ExecuteAsync(context);
},
ResumeAsync = async context =>
{
var instance = await ActivateActivityAsync(context, activityType);
return await instance.ResumeAsync(context);
}
};
}
private async Task ActivateActivityAsync(ActivityExecutionContext context, Type type)
{
var activity = (IDictionaryActivity)ActivatorUtilities.GetServiceOrCreateInstance(context.ServiceProvider, type);
activity.Data = context.GetData();
activity.Id = context.ActivityId;
await SetActivityPropertiesAsync(activity, context);
return activity;
}
private async ValueTask SetActivityPropertiesAsync(IDictionaryActivity activity, ActivityExecutionContext activityExecutionContext)
{
var providers = activityExecutionContext.WorkflowExecutionContext.WorkflowBlueprint.ActivityPropertyProviders.GetProviders(activity.Id);
if (providers == null)
return;
foreach (var provider in providers)
{
try
{
var value = await provider.Value.GetValueAsync(activityExecutionContext, activityExecutionContext.CancellationToken);
activity.Properties[provider.Key] = value;
}
catch (Exception e)
{
throw new CannotSetActivityPropertyValueException($@"An exception was thrown whilst setting '{activity?.GetType().Name}.{provider.Key}'. See the inner exception for further details.", e);
}
}
}
}
}
Contributor guide
Assessment
This issue has not been assessed yet.