elsa-core/src/core/Elsa.Core/ElsaOptionsBuilder.cs
axeleron007 eb388caed1 Setup Elsa Server project with Features #1032
Setup Elsa Server project with Features.
2021-06-18 16:22:57 +03:00

250 lines
9.2 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Elsa.Attributes;
using Elsa.Builders;
using Elsa.Caching;
using Elsa.Persistence;
using Elsa.Services;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Newtonsoft.Json;
using Rebus.DataBus.InMem;
using Rebus.Persistence.InMem;
using Rebus.Transport.InMem;
using Storage.Net.Blobs;
namespace Elsa
{
public class ElsaOptionsBuilder
{
public ElsaOptionsBuilder(IServiceCollection services)
{
ElsaOptions = new ElsaOptions();
Services = services;
AddAutoMapper = () =>
{
// 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.Singleton);
};
services.AddSingleton<InMemNetwork>();
services.AddSingleton<InMemorySubscriberStore>();
services.AddSingleton<InMemDataStore>();
services.AddMemoryCache();
services.AddSingleton<ICacheSignal, CacheSignal>();
DistributedLockingOptionsBuilder = new DistributedLockingOptionsBuilder(this);
}
public ElsaOptions ElsaOptions { get; }
public IServiceCollection Services { get; }
public DistributedLockingOptionsBuilder DistributedLockingOptionsBuilder { get; }
internal Action AddAutoMapper { get; private set; }
internal bool WithCoreActivities { get; set; } = true;
public ElsaOptionsBuilder NoCoreActivities()
{
WithCoreActivities = false;
return this;
}
public ElsaOptionsBuilder WithContainerName(string name)
{
ElsaOptions.ContainerName = name;
return this;
}
public ElsaOptionsBuilder AddFeatures(IEnumerable<Assembly> assemblies, IEnumerable<string> features)
{
foreach (Assembly assembly in assemblies)
{
foreach (Type type in assembly.GetTypes())
{
var attributes = type.GetCustomAttributes(typeof(FeatureAttribute), true);
foreach (Attribute attribute in attributes)
{
if (!features.Contains(((FeatureAttribute)attribute).FeatureName)) continue;
MethodInfo methodInfo = type.GetMethod("ConfigureElsa");
if (methodInfo != null)
{
object[] parametersArray = new object[] { this };
object classInstance = Activator.CreateInstance(type, null);
methodInfo.Invoke(classInstance, parametersArray);
}
}
}
}
return this;
}
public ElsaOptionsBuilder AddActivity<T>() where T : IActivity => AddActivity(typeof(T));
public ElsaOptionsBuilder AddActivity(Type activityType)
{
Services.AddTransient(activityType);
Services.AddTransient(sp => (IActivity) sp.GetRequiredService(activityType));
ElsaOptions.ActivityFactory.Add(activityType, provider => (IActivity) ActivatorUtilities.GetServiceOrCreateInstance(provider, activityType));
return this;
}
public ElsaOptionsBuilder AddActivitiesFrom(Assembly assembly) => AddActivitiesFrom(new[] { assembly });
public ElsaOptionsBuilder AddActivitiesFrom(params Assembly[] assemblies) => AddActivitiesFrom((IEnumerable<Assembly>) assemblies);
public ElsaOptionsBuilder AddActivitiesFrom(params Type[] assemblyMarkerTypes) => AddActivitiesFrom(assemblyMarkerTypes.Select(x => x.Assembly).Distinct());
public ElsaOptionsBuilder AddActivitiesFrom<TMarker>() where TMarker : class => AddActivitiesFrom(typeof(TMarker));
public ElsaOptionsBuilder AddActivitiesFrom(IEnumerable<Assembly> assemblies)
{
var types = assemblies.SelectMany(x => x.GetAllWithInterface<IActivity>());
foreach (var type in types)
AddActivity(type);
return this;
}
public ElsaOptionsBuilder RemoveActivity<T>() where T : IActivity => RemoveActivity(typeof(T));
public ElsaOptionsBuilder RemoveActivity(Type activityType)
{
ElsaOptions.ActivityFactory.Remove(activityType);
return this;
}
public ElsaOptionsBuilder AddWorkflow<T>() where T : IWorkflow => AddWorkflow(typeof(T));
public ElsaOptionsBuilder AddWorkflow(Type workflowType)
{
var workflowFactory = ElsaOptions.WorkflowFactory;
if (workflowFactory.Types.Contains(workflowType))
return this;
Services.AddSingleton(workflowType);
Services.AddSingleton(sp => (IWorkflow) sp.GetRequiredService(workflowType));
workflowFactory.Add(workflowType, provider => (IWorkflow) ActivatorUtilities.GetServiceOrCreateInstance(provider, workflowType));
return this;
}
public ElsaOptionsBuilder AddWorkflow(IWorkflow workflow)
{
Services.AddSingleton(workflow);
ElsaOptions.WorkflowFactory.Add(workflow.GetType(), workflow);
return this;
}
public ElsaOptionsBuilder AddWorkflow<T>(Func<IServiceProvider, T> workflow) where T : class, IWorkflow
{
Services.AddSingleton(workflow);
Services.AddSingleton<IWorkflow>(sp => sp.GetRequiredService<T>());
ElsaOptions.WorkflowFactory.Add(typeof(T), sp => sp.GetRequiredService<T>());
return this;
}
public ElsaOptionsBuilder AddWorkflowsFrom<T>() => AddWorkflowsFrom(typeof(T).Assembly);
public ElsaOptionsBuilder AddWorkflowsFrom(Assembly assembly)
{
var types = assembly.GetAllWithInterface<IWorkflow>();
foreach (var type in types)
AddWorkflow(type);
return this;
}
public ElsaOptionsBuilder RemoveWorkflow<T>() where T : IWorkflow => RemoveWorkflow(typeof(T));
public ElsaOptionsBuilder RemoveWorkflow(Type workflowType)
{
ElsaOptions.WorkflowFactory.Remove(workflowType);
return this;
}
public ElsaOptionsBuilder AddCompetingMessageType(Type messageType)
{
ElsaOptions.CompetingMessageTypes.Add(messageType);
return this;
}
public ElsaOptionsBuilder AddCompetingMessageType<T>() => AddCompetingMessageType(typeof(T));
public ElsaOptionsBuilder AddPubSubMessageType(Type messageType)
{
ElsaOptions.PubSubMessageTypes.Add(messageType);
return this;
}
public ElsaOptionsBuilder AddPubSubMessageType<T>() => AddPubSubMessageType(typeof(T));
public ElsaOptionsBuilder ConfigureDistributedLockProvider(Action<DistributedLockingOptionsBuilder> configureOptions)
{
configureOptions(DistributedLockingOptionsBuilder);
return this;
}
public ElsaOptionsBuilder UseStorage(Func<IBlobStorage> factory) => UseStorage(_ => factory());
public ElsaOptionsBuilder UseStorage(Func<IServiceProvider, IBlobStorage> factory)
{
ElsaOptions.StorageFactory = factory;
return this;
}
public ElsaOptionsBuilder UseWorkflowDefinitionStore(Func<IServiceProvider, IWorkflowDefinitionStore> factory)
{
ElsaOptions.WorkflowDefinitionStoreFactory = factory;
return this;
}
public ElsaOptionsBuilder UseWorkflowInstanceStore(Func<IServiceProvider, IWorkflowInstanceStore> factory)
{
ElsaOptions.WorkflowInstanceStoreFactory = factory;
return this;
}
public ElsaOptionsBuilder UseWorkflowExecutionLogStore(Func<IServiceProvider, IWorkflowExecutionLogStore> factory)
{
ElsaOptions.WorkflowExecutionLogStoreFactory = factory;
return this;
}
public ElsaOptionsBuilder UseWorkflowTriggerStore(Func<IServiceProvider, IBookmarkStore> factory)
{
ElsaOptions.WorkflowTriggerStoreFactory = factory;
return this;
}
public ElsaOptionsBuilder UseAutoMapper(Action addAutoMapper)
{
AddAutoMapper = addAutoMapper;
return this;
}
public ElsaOptionsBuilder UseJsonSerializer(Func<IServiceProvider, JsonSerializer> factory)
{
ElsaOptions.CreateJsonSerializer = factory;
return this;
}
public ElsaOptionsBuilder ConfigureJsonSerializer(Action<IServiceProvider, JsonSerializer> configure)
{
ElsaOptions.JsonSerializerConfigurer = configure;
return this;
}
public ElsaOptionsBuilder UseServiceBus(Action<ServiceBusEndpointConfigurationContext> setup)
{
ElsaOptions.ConfigureServiceBusEndpoint = setup;
return this;
}
}
}