2020-07-14 13:24:07 +00:00
|
|
|
using System;
|
2020-12-26 11:21:08 +00:00
|
|
|
using System.Collections.Generic;
|
2020-12-24 13:25:43 +00:00
|
|
|
using System.Linq;
|
|
|
|
|
using System.Reflection;
|
2020-12-26 11:21:08 +00:00
|
|
|
using Elsa.Builders;
|
2020-01-15 20:26:44 +00:00
|
|
|
using Elsa.Caching;
|
2021-03-30 08:46:50 +00:00
|
|
|
using Elsa.Dispatch;
|
2020-07-14 13:24:07 +00:00
|
|
|
using Elsa.DistributedLock;
|
2021-03-29 20:11:37 +00:00
|
|
|
using Elsa.DistributedLocking;
|
2020-12-26 11:21:08 +00:00
|
|
|
using Elsa.Models;
|
2020-12-12 13:07:17 +00:00
|
|
|
using Elsa.Persistence;
|
|
|
|
|
using Elsa.Persistence.InMemory;
|
2020-10-17 18:19:44 +00:00
|
|
|
using Elsa.Serialization;
|
2020-11-20 22:24:48 +00:00
|
|
|
using Elsa.Services;
|
2020-01-15 20:26:44 +00:00
|
|
|
using Microsoft.Extensions.DependencyInjection;
|
2020-10-17 18:19:44 +00:00
|
|
|
using Newtonsoft.Json;
|
2020-04-19 13:39:28 +00:00
|
|
|
using Rebus.DataBus.InMem;
|
2020-01-15 20:26:44 +00:00
|
|
|
using Rebus.Persistence.InMem;
|
|
|
|
|
using Rebus.Transport.InMem;
|
2020-10-23 12:20:52 +00:00
|
|
|
using Storage.Net;
|
|
|
|
|
using Storage.Net.Blobs;
|
2020-01-15 20:26:44 +00:00
|
|
|
|
|
|
|
|
namespace Elsa
|
|
|
|
|
{
|
2020-12-26 11:21:08 +00:00
|
|
|
public class ElsaOptions
|
2020-01-15 20:26:44 +00:00
|
|
|
{
|
2021-01-08 10:14:00 +00:00
|
|
|
private readonly IList<Type> _messageTypes = new List<Type>();
|
|
|
|
|
|
2020-12-26 11:21:08 +00:00
|
|
|
public ElsaOptions(IServiceCollection services)
|
2020-01-15 20:26:44 +00:00
|
|
|
{
|
|
|
|
|
Services = services;
|
2020-12-14 16:15:39 +00:00
|
|
|
WorkflowDefinitionStoreFactory = sp => ActivatorUtilities.CreateInstance<InMemoryWorkflowDefinitionStore>(sp);
|
|
|
|
|
WorkflowInstanceStoreFactory = sp => ActivatorUtilities.CreateInstance<InMemoryWorkflowInstanceStore>(sp);
|
2020-12-21 16:08:32 +00:00
|
|
|
WorkflowExecutionLogStoreFactory = sp => ActivatorUtilities.CreateInstance<InMemoryWorkflowExecutionLogStore>(sp);
|
2021-01-29 15:16:45 +00:00
|
|
|
WorkflowTriggerStoreFactory = sp => ActivatorUtilities.CreateInstance<InMemoryBookmarkStore>(sp);
|
2021-03-30 08:46:50 +00:00
|
|
|
WorkflowDefinitionDispatcherFactory = sp => ActivatorUtilities.CreateInstance<QueuingWorkflowDispatcher>(sp);
|
|
|
|
|
WorkflowInstanceDispatcherFactory = sp => ActivatorUtilities.CreateInstance<QueuingWorkflowDispatcher>(sp);
|
|
|
|
|
CorrelatingWorkflowDispatcherFactory = sp => ActivatorUtilities.CreateInstance<QueuingWorkflowDispatcher>(sp);
|
2020-10-23 12:20:52 +00:00
|
|
|
StorageFactory = sp => Storage.Net.StorageFactory.Blobs.InMemory();
|
2020-01-15 20:26:44 +00:00
|
|
|
DistributedLockProviderFactory = sp => new DefaultLockProvider();
|
|
|
|
|
SignalFactory = sp => new Signal();
|
2020-11-20 22:24:48 +00:00
|
|
|
JsonSerializerConfigurer = (sp, serializer) => { };
|
|
|
|
|
|
2020-10-20 21:17:08 +00:00
|
|
|
AddAutoMapper = () =>
|
|
|
|
|
{
|
2020-12-24 13:25:43 +00:00
|
|
|
// The profiles are added to AddWorkflowsCore so that they are not forgotten in case the AddAutoMapper function(option) is overridden.
|
|
|
|
|
services.AddAutoMapper(Enumerable.Empty<Assembly>(), serviceLifetime: ServiceLifetime.Singleton);
|
2020-10-20 21:17:08 +00:00
|
|
|
};
|
2020-11-20 12:29:08 +00:00
|
|
|
|
2020-11-20 22:24:48 +00:00
|
|
|
services.AddSingleton<InMemNetwork>();
|
|
|
|
|
services.AddSingleton<InMemorySubscriberStore>();
|
|
|
|
|
services.AddSingleton<InMemDataStore>();
|
2021-01-08 14:02:41 +00:00
|
|
|
services.AddMemoryCache();
|
2020-10-20 21:17:08 +00:00
|
|
|
|
2020-11-20 22:24:48 +00:00
|
|
|
ConfigureServiceBusEndpoint = ConfigureInMemoryServiceBusEndpoint;
|
|
|
|
|
|
2020-10-17 18:19:44 +00:00
|
|
|
CreateJsonSerializer = sp =>
|
|
|
|
|
{
|
2020-10-20 21:17:08 +00:00
|
|
|
var serializer = DefaultContentSerializer.CreateDefaultJsonSerializer();
|
2020-10-17 18:19:44 +00:00
|
|
|
JsonSerializerConfigurer(sp, serializer);
|
|
|
|
|
return serializer;
|
|
|
|
|
};
|
2020-01-15 20:26:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public IServiceCollection Services { get; }
|
2020-12-26 11:21:08 +00:00
|
|
|
public ServiceFactory<IActivity> ActivityFactory { get; } = new();
|
|
|
|
|
public ServiceFactory<IWorkflow> WorkflowFactory { get; } = new();
|
|
|
|
|
public IEnumerable<Type> ActivityTypes => ActivityFactory.Types;
|
|
|
|
|
public IEnumerable<Type> WorkflowTypes => WorkflowFactory.Types;
|
2021-01-08 10:14:00 +00:00
|
|
|
public IEnumerable<Type> MessageTypes => _messageTypes.ToList();
|
|
|
|
|
public ServiceBusOptions ServiceBusOptions { get; } = new();
|
|
|
|
|
|
2020-10-23 12:20:52 +00:00
|
|
|
internal Func<IServiceProvider, IBlobStorage> StorageFactory { get; set; }
|
2020-12-12 13:07:17 +00:00
|
|
|
internal Func<IServiceProvider, IWorkflowDefinitionStore> WorkflowDefinitionStoreFactory { get; set; }
|
|
|
|
|
internal Func<IServiceProvider, IWorkflowInstanceStore> WorkflowInstanceStoreFactory { get; set; }
|
2020-12-21 16:08:32 +00:00
|
|
|
internal Func<IServiceProvider, IWorkflowExecutionLogStore> WorkflowExecutionLogStoreFactory { get; set; }
|
2021-01-29 15:16:45 +00:00
|
|
|
internal Func<IServiceProvider, IBookmarkStore> WorkflowTriggerStoreFactory { get; set; }
|
2020-01-15 20:26:44 +00:00
|
|
|
internal Func<IServiceProvider, IDistributedLockProvider> DistributedLockProviderFactory { get; private set; }
|
|
|
|
|
internal Func<IServiceProvider, ISignal> SignalFactory { get; private set; }
|
2020-10-17 18:19:44 +00:00
|
|
|
internal Func<IServiceProvider, JsonSerializer> CreateJsonSerializer { get; private set; }
|
|
|
|
|
internal Action<IServiceProvider, JsonSerializer> JsonSerializerConfigurer { get; private set; }
|
2021-03-30 08:46:50 +00:00
|
|
|
internal Func<IServiceProvider, IWorkflowDefinitionDispatcher> WorkflowDefinitionDispatcherFactory { get; set; }
|
|
|
|
|
internal Func<IServiceProvider, IWorkflowInstanceDispatcher> WorkflowInstanceDispatcherFactory { get; set; }
|
|
|
|
|
internal Func<IServiceProvider, ICorrelatingWorkflowDispatcher> CorrelatingWorkflowDispatcherFactory { get; set; }
|
2020-10-20 21:17:08 +00:00
|
|
|
internal Action AddAutoMapper { get; private set; }
|
2020-11-20 22:24:48 +00:00
|
|
|
internal Action<ServiceBusEndpointConfigurationContext> ConfigureServiceBusEndpoint { get; private set; }
|
2021-03-26 15:08:15 +00:00
|
|
|
internal bool WithCoreActivities { get; private set; } = true;
|
|
|
|
|
|
|
|
|
|
public ElsaOptions NoCoreActivities()
|
|
|
|
|
{
|
|
|
|
|
WithCoreActivities = false;
|
|
|
|
|
return this;
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-26 11:21:08 +00:00
|
|
|
public ElsaOptions AddActivity<T>() where T : IActivity => AddActivity(typeof(T));
|
|
|
|
|
|
|
|
|
|
public ElsaOptions AddActivity(Type activityType)
|
|
|
|
|
{
|
|
|
|
|
Services.AddTransient(activityType);
|
|
|
|
|
Services.AddTransient(sp => (IActivity) sp.GetRequiredService(activityType));
|
|
|
|
|
ActivityFactory.Add(activityType, provider => (IActivity)ActivatorUtilities.GetServiceOrCreateInstance(provider, activityType));
|
|
|
|
|
return this;
|
|
|
|
|
}
|
|
|
|
|
|
2021-01-30 13:43:32 +00:00
|
|
|
public ElsaOptions AddActivitiesFrom(Assembly assembly) => AddActivitiesFrom(new[] { assembly });
|
|
|
|
|
public ElsaOptions AddActivitiesFrom(params Assembly[] assemblies) => AddActivitiesFrom((IEnumerable<Assembly>) assemblies);
|
2021-02-13 09:29:03 +00:00
|
|
|
public ElsaOptions AddActivitiesFrom(params Type[] assemblyMarkerTypes) => AddActivitiesFrom(assemblyMarkerTypes.Select(x => x.Assembly).Distinct());
|
|
|
|
|
public ElsaOptions AddActivitiesFrom<TMarker>() where TMarker:class => AddActivitiesFrom(typeof(TMarker));
|
2021-01-30 13:43:32 +00:00
|
|
|
|
|
|
|
|
public ElsaOptions AddActivitiesFrom(IEnumerable<Assembly> assemblies)
|
2020-12-26 11:21:08 +00:00
|
|
|
{
|
2021-01-30 13:43:32 +00:00
|
|
|
var types = assemblies.SelectMany(x => x.GetAllWithInterface<IActivity>());
|
2020-12-26 11:21:08 +00:00
|
|
|
|
|
|
|
|
foreach (var type in types)
|
|
|
|
|
AddActivity(type);
|
|
|
|
|
|
|
|
|
|
return this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public ElsaOptions RemoveActivity<T>() where T : IActivity => RemoveActivity(typeof(T));
|
|
|
|
|
|
|
|
|
|
public ElsaOptions RemoveActivity(Type activityType)
|
|
|
|
|
{
|
|
|
|
|
ActivityFactory.Remove(activityType);
|
|
|
|
|
return this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public ElsaOptions AddWorkflow<T>() where T : IWorkflow => AddWorkflow(typeof(T));
|
|
|
|
|
|
|
|
|
|
public ElsaOptions AddWorkflow(Type workflowType)
|
|
|
|
|
{
|
|
|
|
|
Services.AddSingleton(workflowType);
|
|
|
|
|
Services.AddSingleton(sp => (IWorkflow)sp.GetRequiredService(workflowType));
|
|
|
|
|
WorkflowFactory.Add(workflowType, provider => (IWorkflow)ActivatorUtilities.GetServiceOrCreateInstance(provider, workflowType));
|
|
|
|
|
return this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public ElsaOptions AddWorkflow(IWorkflow workflow)
|
|
|
|
|
{
|
|
|
|
|
Services.AddSingleton(workflow);
|
|
|
|
|
WorkflowFactory.Add(workflow.GetType(), workflow);
|
|
|
|
|
return this;
|
|
|
|
|
}
|
2021-01-01 16:58:08 +00:00
|
|
|
|
|
|
|
|
public ElsaOptions AddWorkflow<T>(Func<IServiceProvider, T> workflow) where T: class, IWorkflow
|
|
|
|
|
{
|
2021-03-30 08:46:50 +00:00
|
|
|
Services.AddSingleton(workflow);
|
2021-01-01 16:58:08 +00:00
|
|
|
Services.AddSingleton<IWorkflow>(sp => sp.GetRequiredService<T>());
|
|
|
|
|
WorkflowFactory.Add(typeof(T), sp => sp.GetRequiredService<T>());
|
|
|
|
|
|
|
|
|
|
return this;
|
|
|
|
|
}
|
2020-12-26 20:55:02 +00:00
|
|
|
|
|
|
|
|
public ElsaOptions AddWorkflowsFrom<T>() => AddWorkflowsFrom(typeof(T).Assembly);
|
2020-12-26 11:21:08 +00:00
|
|
|
|
2020-12-26 13:37:05 +00:00
|
|
|
public ElsaOptions AddWorkflowsFrom(Assembly assembly)
|
2020-12-26 11:21:08 +00:00
|
|
|
{
|
|
|
|
|
var types = assembly.GetAllWithInterface<IWorkflow>();
|
|
|
|
|
|
|
|
|
|
foreach (var type in types)
|
|
|
|
|
AddWorkflow(type);
|
|
|
|
|
|
|
|
|
|
return this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public ElsaOptions RemoveWorkflow<T>() where T : IWorkflow => RemoveWorkflow(typeof(T));
|
|
|
|
|
|
|
|
|
|
public ElsaOptions RemoveWorkflow(Type workflowType)
|
|
|
|
|
{
|
|
|
|
|
WorkflowFactory.Remove(workflowType);
|
|
|
|
|
return this;
|
|
|
|
|
}
|
2020-01-15 20:26:44 +00:00
|
|
|
|
2021-01-08 10:14:00 +00:00
|
|
|
public ElsaOptions AddMessageType(Type messageType)
|
|
|
|
|
{
|
|
|
|
|
_messageTypes.Add(messageType);
|
|
|
|
|
return this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public ElsaOptions AddMessageType<T>() => AddMessageType(typeof(T));
|
|
|
|
|
|
2020-12-26 11:21:08 +00:00
|
|
|
public ElsaOptions UseDistributedLockProvider(Func<IServiceProvider, IDistributedLockProvider> factory)
|
2020-01-15 20:26:44 +00:00
|
|
|
{
|
|
|
|
|
DistributedLockProviderFactory = factory;
|
|
|
|
|
return this;
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-26 11:21:08 +00:00
|
|
|
public ElsaOptions UseSignal(Func<IServiceProvider, ISignal> factory)
|
2020-01-15 20:26:44 +00:00
|
|
|
{
|
|
|
|
|
SignalFactory = factory;
|
|
|
|
|
return this;
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-26 11:21:08 +00:00
|
|
|
public ElsaOptions UseStorage(Func<IBlobStorage> factory) => UseStorage(_ => factory());
|
2020-10-23 12:38:26 +00:00
|
|
|
|
2020-12-26 11:21:08 +00:00
|
|
|
public ElsaOptions UseStorage(Func<IServiceProvider, IBlobStorage> factory)
|
2020-10-23 12:20:52 +00:00
|
|
|
{
|
|
|
|
|
StorageFactory = factory;
|
|
|
|
|
return this;
|
|
|
|
|
}
|
2020-12-12 13:07:17 +00:00
|
|
|
|
2020-12-26 11:21:08 +00:00
|
|
|
public ElsaOptions UseWorkflowDefinitionStore(Func<IServiceProvider, IWorkflowDefinitionStore> factory)
|
2020-12-12 13:07:17 +00:00
|
|
|
{
|
|
|
|
|
WorkflowDefinitionStoreFactory = factory;
|
|
|
|
|
return this;
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-26 11:21:08 +00:00
|
|
|
public ElsaOptions UseWorkflowInstanceStore(Func<IServiceProvider, IWorkflowInstanceStore> factory)
|
2020-12-12 13:07:17 +00:00
|
|
|
{
|
|
|
|
|
WorkflowInstanceStoreFactory = factory;
|
|
|
|
|
return this;
|
|
|
|
|
}
|
2020-12-21 16:08:32 +00:00
|
|
|
|
2020-12-26 11:21:08 +00:00
|
|
|
public ElsaOptions UseWorkflowExecutionLogStore(Func<IServiceProvider, IWorkflowExecutionLogStore> factory)
|
2020-12-21 16:08:32 +00:00
|
|
|
{
|
|
|
|
|
WorkflowExecutionLogStoreFactory = factory;
|
|
|
|
|
return this;
|
|
|
|
|
}
|
2021-01-29 15:16:45 +00:00
|
|
|
|
|
|
|
|
public ElsaOptions UseWorkflowTriggerStore(Func<IServiceProvider, IBookmarkStore> factory)
|
|
|
|
|
{
|
|
|
|
|
WorkflowTriggerStoreFactory = factory;
|
|
|
|
|
return this;
|
|
|
|
|
}
|
2020-11-20 22:24:48 +00:00
|
|
|
|
2020-12-26 11:21:08 +00:00
|
|
|
public ElsaOptions UseAutoMapper(Action addAutoMapper)
|
2020-10-20 21:17:08 +00:00
|
|
|
{
|
|
|
|
|
AddAutoMapper = addAutoMapper;
|
|
|
|
|
return this;
|
|
|
|
|
}
|
2020-10-10 19:10:09 +00:00
|
|
|
|
2020-12-26 11:21:08 +00:00
|
|
|
public ElsaOptions UseJsonSerializer(Func<IServiceProvider, JsonSerializer> factory)
|
2020-10-17 18:19:44 +00:00
|
|
|
{
|
|
|
|
|
CreateJsonSerializer = factory;
|
|
|
|
|
return this;
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-26 11:21:08 +00:00
|
|
|
public ElsaOptions ConfigureJsonSerializer(Action<IServiceProvider, JsonSerializer> configure)
|
2020-10-17 18:19:44 +00:00
|
|
|
{
|
|
|
|
|
JsonSerializerConfigurer = configure;
|
|
|
|
|
return this;
|
|
|
|
|
}
|
2020-01-15 20:26:44 +00:00
|
|
|
|
2020-12-26 11:21:08 +00:00
|
|
|
public ElsaOptions UseServiceBus(Action<ServiceBusEndpointConfigurationContext> setup)
|
2020-11-20 22:24:48 +00:00
|
|
|
{
|
|
|
|
|
ConfigureServiceBusEndpoint = setup;
|
|
|
|
|
return this;
|
|
|
|
|
}
|
|
|
|
|
|
2021-01-08 10:14:00 +00:00
|
|
|
private void ConfigureInMemoryServiceBusEndpoint(ServiceBusEndpointConfigurationContext context)
|
2020-11-20 22:24:48 +00:00
|
|
|
{
|
|
|
|
|
var serviceProvider = context.ServiceProvider;
|
|
|
|
|
var transport = serviceProvider.GetService<InMemNetwork>();
|
|
|
|
|
var store = serviceProvider.GetRequiredService<InMemorySubscriberStore>();
|
|
|
|
|
var queueName = context.QueueName;
|
|
|
|
|
|
|
|
|
|
context.Configurer
|
|
|
|
|
.Subscriptions(s => s.StoreInMemory(store))
|
2021-01-30 19:39:08 +00:00
|
|
|
.Transport(t => t.UseInMemoryTransport(transport, queueName));
|
2020-01-15 20:26:44 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|