Fix Webhooks service registration

This commit is contained in:
Sipke Schoorstra 2021-09-14 15:07:25 +02:00
parent fa4da6f841
commit 11566a2b76
4 changed files with 52 additions and 33 deletions

View file

@ -14,6 +14,7 @@ using Elsa.Webhooks.Models;
using Elsa.Webhooks.Persistence;
using Humanizer;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
namespace Elsa.Activities.Webhooks.ActivityTypes
{
@ -23,23 +24,23 @@ namespace Elsa.Activities.Webhooks.ActivityTypes
private const string WebhooksActivityTypeSuffix = "Webhook";
private const string WebhooksActivityCategory = "Webhooks";
private readonly IWebhookDefinitionStore _webhookDefinitionStore;
private readonly IActivityActivator _activityActivator;
private readonly IServiceScopeFactory _serviceScopeFactory;
public WebhookActivityTypeProvider(
IWebhookDefinitionStore webhookDefinitionStore,
IActivityActivator activityActivator)
public WebhookActivityTypeProvider(IActivityActivator activityActivator, IServiceScopeFactory serviceScopeFactory)
{
_webhookDefinitionStore = webhookDefinitionStore;
_activityActivator = activityActivator;
_serviceScopeFactory = serviceScopeFactory;
}
public async ValueTask<IEnumerable<ActivityType>> GetActivityTypesAsync(CancellationToken cancellationToken = default)
{
using var scope = _serviceScopeFactory.CreateScope();
var webhookDefinitionStore = scope.ServiceProvider.GetRequiredService<IWebhookDefinitionStore>();
var specification = Specification<WebhookDefinition>.Identity;
var definitions = await _webhookDefinitionStore.FindManyAsync(specification, cancellationToken: cancellationToken);
var definitions = await webhookDefinitionStore.FindManyAsync(specification, cancellationToken: cancellationToken);
var activityTypes = new List<ActivityType>();
foreach (var definition in definitions)
{
var activity = CreateWebhookActivityType(definition);
@ -53,7 +54,7 @@ namespace Elsa.Activities.Webhooks.ActivityTypes
{
var activityTypeName = webhook.Name.EndsWith(WebhooksActivityTypeSuffix) ? webhook.Name : $"{webhook.Name}{WebhooksActivityTypeSuffix}";
var activityDisplayName = activityTypeName.Humanize();
ValueTask<ActivityDescriptor> CreateDescriptorAsync()
{
var descriptor = new ActivityDescriptor
@ -105,7 +106,7 @@ namespace Elsa.Activities.Webhooks.ActivityTypes
};
return new ValueTask<ActivityDescriptor>(descriptor);
};
}
async ValueTask<IActivity> ActivateActivityAsync(ActivityExecutionContext context)
{

View file

@ -1,22 +1,40 @@
using System;
using Elsa.Activities.Webhooks.ActivityTypes;
using Elsa.Activities.Webhooks.Bookmarks;
using Elsa.Activities.Webhooks.Handlers;
using Elsa.Activities.Webhooks.Options;
using Elsa.Activities.Webhooks.Persistence.Decorators;
using Elsa.Options;
using Elsa.Providers.Activities;
using Elsa.Webhooks.Persistence;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
namespace Elsa.Activities.Webhooks.Extensions
{
public static class WebhookOptionsBuilderExtensions
{
public static ElsaOptionsBuilder AddWebhooks(this ElsaOptionsBuilder elsaOptions)
public static ElsaOptionsBuilder AddWebhooks(this ElsaOptionsBuilder elsaOptions, Action<WebhookOptionsBuilder>? configureOptions = default)
{
elsaOptions.Services
.AddScoped<IActivityTypeProvider, WebhookActivityTypeProvider>()
var services = elsaOptions.Services;
var optionsBuilder = new WebhookOptionsBuilder(services);
services.Configure<WebhookOptions>(webhookOptions =>
{
configureOptions?.Invoke(optionsBuilder);
optionsBuilder.ApplyTo(webhookOptions);
});
services
.AddScoped(sp => sp.GetRequiredService<IOptions<WebhookOptions>>().Value.WebhookDefinitionStoreFactory(sp))
.AddActivityTypeProvider<WebhookActivityTypeProvider>()
.AddBookmarkProvider<WebhookBookmarkProvider>()
.AddNotificationHandlersFrom<EvictWorkflowRegistryCacheHandler>();
services.Decorate<IWebhookDefinitionStore, InitializingWebhookDefinitionStore>();
services.Decorate<IWebhookDefinitionStore, EventPublishingWebhookDefinitionStore>();
return elsaOptions;
}
}
}
}

View file

@ -8,12 +8,14 @@ namespace Elsa.Activities.Webhooks
{
public class WebhookOptionsBuilder
{
public WebhookOptionsBuilder(IServiceCollection services)
public WebhookOptionsBuilder(IServiceCollection services) : this(services, new WebhookOptions())
{
}
public WebhookOptionsBuilder(IServiceCollection services, WebhookOptions webhookOptions)
{
WebhookOptions = new WebhookOptions();
Services = services;
services.AddMemoryCache();
services.AddSingleton<ICacheSignal, CacheSignal>();
WebhookOptions = webhookOptions;
}
public WebhookOptions WebhookOptions { get; }
@ -24,5 +26,10 @@ namespace Elsa.Activities.Webhooks
WebhookOptions.WebhookDefinitionStoreFactory = factory;
return this;
}
public void ApplyTo(WebhookOptions webhookOptions)
{
webhookOptions.WebhookDefinitionStoreFactory = WebhookOptions.WebhookDefinitionStoreFactory;
}
}
}
}

View file

@ -1,6 +1,6 @@
using System;
using Elsa.Activities.Webhooks;
using Elsa.Activities.Webhooks.Persistence.Decorators;
using Elsa.Activities.Webhooks.Options;
using Elsa.Options;
using Elsa.Services.Startup;
using Elsa.Webhooks.Persistence.EntityFramework.Core.Extensions;
@ -16,33 +16,26 @@ namespace Elsa.Webhooks.Persistence.EntityFramework.Core
public override void ConfigureElsa(ElsaOptionsBuilder elsa, IConfiguration configuration)
{
var services = elsa.Services;
var section = configuration.GetSection($"Elsa:Features:Webhooks");
var connectionStringName = section.GetValue<string>("ConnectionStringIdentifier");
var connectionString = section.GetValue<string>("ConnectionString");
if (string.IsNullOrWhiteSpace(connectionString))
{
if (string.IsNullOrWhiteSpace(connectionStringName))
connectionStringName = ProviderName;
if (string.IsNullOrWhiteSpace(connectionStringName))
connectionStringName = ProviderName;
if (string.IsNullOrWhiteSpace(connectionString))
connectionString = configuration.GetConnectionString(connectionStringName);
}
if (string.IsNullOrWhiteSpace(connectionString))
connectionString = GetDefaultConnectionString();
var webhookOptionsBuilder = new WebhookOptionsBuilder(services);
webhookOptionsBuilder.UseEntityFrameworkPersistence(options => Configure(options, connectionString));
var optionsBuilder = new WebhookOptionsBuilder(elsa.Services);
optionsBuilder.UseEntityFrameworkPersistence(ef => Configure(ef, connectionString));
services.AddScoped(sp => webhookOptionsBuilder.WebhookOptions.WebhookDefinitionStoreFactory(sp));
services.Decorate<IWebhookDefinitionStore, InitializingWebhookDefinitionStore>();
services.Decorate<IWebhookDefinitionStore, EventPublishingWebhookDefinitionStore>();
elsa.Services.Configure<WebhookOptions>(options => optionsBuilder.ApplyTo(options));
}
protected virtual string GetDefaultConnectionString() => throw new Exception($"No connection string specified for the {ProviderName} provider");
protected abstract void Configure(DbContextOptionsBuilder options, string connectionString);
}
}