Extract options and UI hint resolvers

This commit is contained in:
Sipke Schoorstra 2021-03-10 20:21:18 +01:00
parent 0442e1e699
commit 4eb3f47d30
6 changed files with 94 additions and 39 deletions

View file

@ -0,0 +1,9 @@
using System.Reflection;
namespace Elsa.Metadata
{
public interface IActivityPropertyOptionsResolver
{
object? GetOptions(PropertyInfo activityPropertyInfo);
}
}

View file

@ -0,0 +1,9 @@
using System.Reflection;
namespace Elsa.Metadata
{
public interface IActivityPropertyUIHintResolver
{
string GetUIHint(PropertyInfo activityPropertyInfo);
}
}

View file

@ -131,7 +131,10 @@ namespace Microsoft.Extensions.DependencyInjection
.AddWorkflowProvider<DatabaseWorkflowProvider>();
// Metadata.
services.AddSingleton<IActivityDescriber, ActivityDescriber>();
services
.AddSingleton<IActivityDescriber, ActivityDescriber>()
.AddSingleton<IActivityPropertyOptionsResolver, ActivityPropertyOptionsResolver>()
.AddSingleton<IActivityPropertyUIHintResolver, ActivityPropertyUIHintResolver>();
// Bookmarks.
services

View file

@ -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<ActivityPropertyDescriptor> 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;
}
}
}

View file

@ -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<ActivityPropertyAttribute>();
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);
}
}
}

View file

@ -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<ActivityPropertyAttribute>();
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;
}
}
}