diff --git a/src/core/Elsa.Abstractions/Metadata/IActivityPropertyOptionsResolver.cs b/src/core/Elsa.Abstractions/Metadata/IActivityPropertyOptionsResolver.cs new file mode 100644 index 000000000..0d01e73ff --- /dev/null +++ b/src/core/Elsa.Abstractions/Metadata/IActivityPropertyOptionsResolver.cs @@ -0,0 +1,9 @@ +using System.Reflection; + +namespace Elsa.Metadata +{ + public interface IActivityPropertyOptionsResolver + { + object? GetOptions(PropertyInfo activityPropertyInfo); + } +} \ No newline at end of file diff --git a/src/core/Elsa.Abstractions/Metadata/IActivityPropertyUIHintResolver.cs b/src/core/Elsa.Abstractions/Metadata/IActivityPropertyUIHintResolver.cs new file mode 100644 index 000000000..fa32a0e80 --- /dev/null +++ b/src/core/Elsa.Abstractions/Metadata/IActivityPropertyUIHintResolver.cs @@ -0,0 +1,9 @@ +using System.Reflection; + +namespace Elsa.Metadata +{ + public interface IActivityPropertyUIHintResolver + { + string GetUIHint(PropertyInfo activityPropertyInfo); + } +} \ No newline at end of file diff --git a/src/core/Elsa.Core/Extensions/ElsaServiceCollectionExtensions.cs b/src/core/Elsa.Core/Extensions/ElsaServiceCollectionExtensions.cs index ca7aa71e9..cfb7402d4 100644 --- a/src/core/Elsa.Core/Extensions/ElsaServiceCollectionExtensions.cs +++ b/src/core/Elsa.Core/Extensions/ElsaServiceCollectionExtensions.cs @@ -131,7 +131,10 @@ namespace Microsoft.Extensions.DependencyInjection .AddWorkflowProvider(); // Metadata. - services.AddSingleton(); + services + .AddSingleton() + .AddSingleton() + .AddSingleton(); // Bookmarks. services diff --git a/src/core/Elsa.Core/Metadata/ActivityDescriber.cs b/src/core/Elsa.Core/Metadata/ActivityDescriber.cs index ad0bc292b..3f74c757f 100644 --- a/src/core/Elsa.Core/Metadata/ActivityDescriber.cs +++ b/src/core/Elsa.Core/Metadata/ActivityDescriber.cs @@ -1,24 +1,22 @@ using System; -using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Reflection; using Elsa.Attributes; -using Elsa.Design; using Humanizer; -using Microsoft.Extensions.DependencyInjection; -using Newtonsoft.Json.Linq; namespace Elsa.Metadata { public class ActivityDescriber : IActivityDescriber { - private readonly IServiceProvider _serviceProvider; + private readonly IActivityPropertyOptionsResolver _optionsResolver; + private readonly IActivityPropertyUIHintResolver _uiHintResolver; - public ActivityDescriber(IServiceProvider serviceProvider) + public ActivityDescriber(IActivityPropertyOptionsResolver optionsResolver, IActivityPropertyUIHintResolver uiHintResolver) { - _serviceProvider = serviceProvider; + _optionsResolver = optionsResolver; + _uiHintResolver = uiHintResolver; } public ActivityDescriptor? Describe(Type activityType) @@ -50,7 +48,6 @@ namespace Elsa.Metadata private IEnumerable DescribeProperties(Type activityType) { var properties = activityType.GetProperties(); - using var scope = _serviceProvider.CreateScope(); foreach (var propertyInfo in properties) { @@ -59,43 +56,15 @@ namespace Elsa.Metadata if (activityPropertyAttribute == null) continue; - var options = GetOptions(propertyInfo, activityPropertyAttribute, scope); - yield return new ActivityPropertyDescriptor ( (activityPropertyAttribute.Name ?? propertyInfo.Name).Pascalize(), - (activityPropertyAttribute.UIHint ?? InferPropertyUIHint(propertyInfo)), + _uiHintResolver.GetUIHint(propertyInfo), activityPropertyAttribute.Label ?? propertyInfo.Name.Humanize(LetterCasing.Title), activityPropertyAttribute.Hint, - options + _optionsResolver.GetOptions(propertyInfo) ); } } - - private object? GetOptions(PropertyInfo activityProperty, ActivityPropertyAttribute activityPropertyAttribute, IServiceScope scope) - { - if (activityPropertyAttribute.OptionsProvider == null) - return activityPropertyAttribute.Options; - - var providerType = activityPropertyAttribute.OptionsProvider; - var provider = (IActivityPropertyOptionsProvider) ActivatorUtilities.GetServiceOrCreateInstance(scope.ServiceProvider, providerType); - return provider.GetOptions(activityProperty); - } - - private string InferPropertyUIHint(PropertyInfo propertyInfo) - { - var type = propertyInfo.PropertyType; - - if (type == typeof(bool) || type == typeof(bool?)) - return ActivityPropertyUIHints.Checkbox; - - if (type == typeof(string)) - return ActivityPropertyUIHints.SingleLine; - - if (typeof(IEnumerable).IsAssignableFrom(type)) - return ActivityPropertyUIHints.Dropdown; - - return ActivityPropertyUIHints.SingleLine; - } } } \ No newline at end of file diff --git a/src/core/Elsa.Core/Metadata/ActivityPropertyOptionsResolver.cs b/src/core/Elsa.Core/Metadata/ActivityPropertyOptionsResolver.cs new file mode 100644 index 000000000..7448876c2 --- /dev/null +++ b/src/core/Elsa.Core/Metadata/ActivityPropertyOptionsResolver.cs @@ -0,0 +1,34 @@ +using System; +using System.Reflection; +using Elsa.Attributes; +using Microsoft.Extensions.DependencyInjection; + +namespace Elsa.Metadata +{ + public class ActivityPropertyOptionsResolver : IActivityPropertyOptionsResolver + { + private readonly IServiceProvider _serviceProvider; + + public ActivityPropertyOptionsResolver(IServiceProvider serviceProvider) + { + _serviceProvider = serviceProvider; + } + + public object? GetOptions(PropertyInfo activityPropertyInfo) + { + var activityPropertyAttribute = activityPropertyInfo.GetCustomAttribute(); + + if (activityPropertyAttribute == null) + return null; + + if (activityPropertyAttribute.OptionsProvider == null) + return activityPropertyAttribute.Options; + + var providerType = activityPropertyAttribute.OptionsProvider; + + using var scope = _serviceProvider.CreateScope(); + var provider = (IActivityPropertyOptionsProvider) ActivatorUtilities.GetServiceOrCreateInstance(scope.ServiceProvider, providerType); + return provider.GetOptions(activityPropertyInfo); + } + } +} \ No newline at end of file diff --git a/src/core/Elsa.Core/Metadata/ActivityPropertyUIHintResolver.cs b/src/core/Elsa.Core/Metadata/ActivityPropertyUIHintResolver.cs new file mode 100644 index 000000000..6fdcded6d --- /dev/null +++ b/src/core/Elsa.Core/Metadata/ActivityPropertyUIHintResolver.cs @@ -0,0 +1,31 @@ +using System.Collections; +using System.Reflection; +using Elsa.Attributes; +using Elsa.Design; + +namespace Elsa.Metadata +{ + public class ActivityPropertyUIHintResolver : IActivityPropertyUIHintResolver + { + public string GetUIHint(PropertyInfo activityPropertyInfo) + { + var activityPropertyAttribute = activityPropertyInfo.GetCustomAttribute(); + + if (activityPropertyAttribute.UIHint != null) + return activityPropertyAttribute.UIHint; + + var type = activityPropertyInfo.PropertyType; + + if (type == typeof(bool) || type == typeof(bool?)) + return ActivityPropertyUIHints.Checkbox; + + if (type == typeof(string)) + return ActivityPropertyUIHints.SingleLine; + + if (typeof(IEnumerable).IsAssignableFrom(type)) + return ActivityPropertyUIHints.Dropdown; + + return ActivityPropertyUIHints.SingleLine; + } + } +} \ No newline at end of file