< Summary

Information
Class: Elsa.Workflows.ActivityRegistry
Assembly: Elsa.Workflows.Core
File(s): /home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Workflows.Core/Services/ActivityRegistry.cs
Line coverage
62%
Covered lines: 47
Uncovered lines: 28
Coverable lines: 75
Total lines: 167
Line coverage: 62.6%
Branch coverage
68%
Covered branches: 15
Total branches: 22
Branch coverage: 68.1%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
Add(...)100%11100%
Remove(...)100%11100%
ListAll()100%210%
ListByProvider(...)50%22100%
Find(...)100%11100%
Find(...)100%22100%
Find(...)100%11100%
FindMany(...)100%210%
Register(...)100%210%
RegisterAsync()100%22100%
RegisterAsync()100%22100%
GetDescriptorsAsync(...)100%210%
RefreshDescriptorsAsync()100%44100%
RefreshDescriptorsAsync()0%620%
Add(...)100%11100%
Add(...)83.33%6681.81%
Clear()100%210%
ClearProvider(...)0%620%
GetOrCreateDescriptors(...)50%3240%

File(s)

/home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Workflows.Core/Services/ActivityRegistry.cs

#LineLine coverage
 1using System.Collections.Concurrent;
 2using System.Diagnostics.CodeAnalysis;
 3using Elsa.Workflows.Helpers;
 4using Elsa.Workflows.Models;
 5using Microsoft.Extensions.Logging;
 6
 7namespace Elsa.Workflows;
 8
 9/// <inheritdoc />
 52810public class ActivityRegistry(IActivityDescriber activityDescriber, IEnumerable<IActivityDescriptorModifier> modifiers, 
 11{
 52812    private readonly ISet<ActivityDescriptor> _manualActivityDescriptors = new HashSet<ActivityDescriptor>();
 52813    private ConcurrentDictionary<Type, ICollection<ActivityDescriptor>> _providedActivityDescriptors = new();
 52814    private ConcurrentDictionary<(string Type, int Version), ActivityDescriptor> _activityDescriptors = new();
 15
 16    /// <inheritdoc />
 6417    public void Add(Type providerType, ActivityDescriptor descriptor) => Add(descriptor, GetOrCreateDescriptors(provider
 18
 19    /// <inheritdoc />
 20    public void Remove(Type providerType, ActivityDescriptor descriptor)
 21    {
 622        _providedActivityDescriptors[providerType].Remove(descriptor);
 623        _activityDescriptors.Remove((descriptor.TypeName, descriptor.Version), out _);
 624    }
 25
 26    /// <inheritdoc />
 027    public IEnumerable<ActivityDescriptor> ListAll() => _activityDescriptors.Values;
 28
 29    /// <inheritdoc />
 38130    public IEnumerable<ActivityDescriptor> ListByProvider(Type providerType) => _providedActivityDescriptors.TryGetValue
 31
 32    /// <inheritdoc />
 313733    public ActivityDescriptor? Find(string type) => _activityDescriptors.Values.Where(x => x.TypeName == type).MaxBy(x =
 34
 35    /// <inheritdoc />
 2538836    public ActivityDescriptor? Find(string type, int version) => _activityDescriptors.TryGetValue((type, version), out v
 37
 38    /// <inheritdoc />
 52739    public ActivityDescriptor? Find(Func<ActivityDescriptor, bool> predicate) => _activityDescriptors.Values.FirstOrDefa
 40
 41    /// <inheritdoc />
 042    public IEnumerable<ActivityDescriptor> FindMany(Func<ActivityDescriptor, bool> predicate) => _activityDescriptors.Va
 43
 44    /// <inheritdoc />
 45    public void Register(ActivityDescriptor descriptor)
 46    {
 047        Add(GetType(), descriptor);
 048    }
 49
 50    /// <inheritdoc />
 51    public async Task RegisterAsync([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] Type a
 52    {
 692253        var activityTypeName = ActivityTypeNameHelper.GenerateTypeName(activityType);
 54
 16771155        if (_activityDescriptors.Values.Any(x => x.TypeName == activityTypeName))
 591256            return;
 57
 101058        var activityDescriptor = await activityDescriber.DescribeActivityAsync(activityType, cancellationToken);
 59
 101060        Add(activityDescriptor, _activityDescriptors, _manualActivityDescriptors);
 101061        _manualActivityDescriptors.Add(activityDescriptor);
 692262    }
 63
 64    /// <inheritdoc />
 65    public async Task RegisterAsync(IEnumerable<Type> activityTypes, CancellationToken cancellationToken = default)
 66    {
 1679067        foreach (var activityType in activityTypes)
 650868            await RegisterAsync(activityType, cancellationToken);
 188769    }
 70
 71    /// <inheritdoc />
 072    public ValueTask<IEnumerable<ActivityDescriptor>> GetDescriptorsAsync(CancellationToken cancellationToken = default)
 73
 74    /// <inheritdoc />
 75    public async Task RefreshDescriptorsAsync(IEnumerable<IActivityProvider> activityProviders, CancellationToken cancel
 76    {
 87077        var providersDictionary = new ConcurrentDictionary<Type, ICollection<ActivityDescriptor>>();
 87078        var activityDescriptors = new ConcurrentDictionary<(string Type, int Version), ActivityDescriptor>(_activityDesc
 272479        foreach (var activityProvider in activityProviders)
 80        {
 49281            var descriptors = (await activityProvider.GetDescriptorsAsync(cancellationToken)).ToList();
 49282            var providerDescriptors = new List<ActivityDescriptor>();
 49283            providersDictionary[activityProvider.GetType()] = providerDescriptors;
 2293484            foreach (var descriptor in descriptors)
 85            {
 1097586                Add(descriptor, activityDescriptors, providerDescriptors);
 87            }
 49288        }
 89
 87090        Interlocked.Exchange(ref _activityDescriptors, activityDescriptors);
 87091        Interlocked.Exchange(ref _providedActivityDescriptors, providersDictionary);
 87092    }
 93
 94    public async Task RefreshDescriptorsAsync(IActivityProvider activityProvider, CancellationToken cancellationToken = 
 95    {
 096        var providersDictionary = new ConcurrentDictionary<Type, ICollection<ActivityDescriptor>>(_providedActivityDescr
 097        var activityDescriptors = new ConcurrentDictionary<(string Type, int Version), ActivityDescriptor>(_activityDesc
 098        var descriptors = (await activityProvider.GetDescriptorsAsync(cancellationToken)).ToList();
 099        var providerDescriptors = new List<ActivityDescriptor>();
 0100        providersDictionary[activityProvider.GetType()] = providerDescriptors;
 101
 0102        foreach (var descriptor in descriptors)
 0103            Add(descriptor, activityDescriptors, providerDescriptors);
 104
 0105        Interlocked.Exchange(ref _activityDescriptors, activityDescriptors);
 0106        Interlocked.Exchange(ref _providedActivityDescriptors, providersDictionary);
 0107    }
 108
 109    private void Add(ActivityDescriptor descriptor, ICollection<ActivityDescriptor> target)
 110    {
 64111        Add(descriptor, _activityDescriptors, target);
 64112    }
 113
 114    private void Add(ActivityDescriptor? descriptor, ConcurrentDictionary<(string Type, int Version), ActivityDescriptor
 115    {
 12049116        if (descriptor is null)
 117        {
 0118            logger.LogError("Unable to add a null descriptor");
 0119            return;
 120        }
 121
 48618122        foreach (var modifier in modifiers)
 12260123            modifier.Modify(descriptor);
 124
 125        // If the descriptor already exists, replace it. But log a warning.
 12049126        if (activityDescriptors.TryGetValue((descriptor.TypeName, descriptor.Version), out var existingDescriptor))
 127        {
 128            // Remove the existing descriptor from the providerDescriptors collection.
 5936129            providerDescriptors.Remove(existingDescriptor);
 130
 131            // Log a warning.
 5936132            logger.LogWarning("Activity descriptor {ActivityType} v{ActivityVersion} was already registered. Replacing w
 133        }
 134
 12049135        activityDescriptors[(descriptor.TypeName, descriptor.Version)] = descriptor;
 12049136        providerDescriptors.Add(descriptor);
 12049137    }
 138
 139    /// <inheritdoc />
 140    public void Clear()
 141    {
 0142        _activityDescriptors.Clear();
 0143        _providedActivityDescriptors.Clear();
 0144    }
 145
 146    /// <inheritdoc />
 147    public void ClearProvider(Type providerType)
 148    {
 0149        var descriptors = ListByProvider(providerType).ToList();
 150
 0151        foreach (var descriptor in descriptors)
 0152            _activityDescriptors.Remove((descriptor.TypeName, descriptor.Version), out _);
 153
 0154        _providedActivityDescriptors.Remove(providerType, out _);
 0155    }
 156
 157    private ICollection<ActivityDescriptor> GetOrCreateDescriptors(Type provider)
 158    {
 64159        if (_providedActivityDescriptors.TryGetValue(provider, out var descriptors))
 64160            return descriptors;
 161
 0162        descriptors = new List<ActivityDescriptor>();
 0163        _providedActivityDescriptors[provider] = descriptors;
 164
 0165        return descriptors;
 166    }
 167}