Refactor persistence configuration (memory + EF core)
This commit is contained in:
parent
1afe3a62a0
commit
5f83198677
|
|
@ -1,5 +1,6 @@
|
|||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Computables/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Configurer/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=materializer/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Materializers/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Pomelo/@EntryIndexedValue">True</s:Boolean>
|
||||
|
|
|
|||
|
|
@ -19,11 +19,13 @@ public class ElsaOptionsConfigurator
|
|||
|
||||
public IServiceCollection Services { get; }
|
||||
|
||||
public T Configure<T>(Action<T>? configure = default) where T : class, IConfigurator, new()
|
||||
public T Configure<T>(Action<T>? configure = default) where T : class, IConfigurator, new() => Configure<T>(() => new T(), configure);
|
||||
|
||||
public T Configure<T>(Func<T> factory, Action<T>? configure = default) where T : class, IConfigurator
|
||||
{
|
||||
if (_configurators.FirstOrDefault(x => x is T) is not T configurator)
|
||||
{
|
||||
configurator = new T();
|
||||
configurator = factory();
|
||||
_configurators.Add(configurator);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Elsa.Options;
|
||||
using Elsa.Persistence.Options;
|
||||
|
||||
namespace Elsa.Persistence.Extensions;
|
||||
|
||||
public static class ServiceCollectionExtensions
|
||||
{
|
||||
public static IServiceCollection AddPersistenceServices(this IServiceCollection services)
|
||||
public static ElsaOptionsConfigurator UsePersistence(this ElsaOptionsConfigurator configurator, Action<PersistenceOptions>? configure = default)
|
||||
{
|
||||
return services;
|
||||
configurator.Configure(() => new PersistenceOptions(configurator), configure);
|
||||
return configurator;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
using Elsa.Options;
|
||||
using Elsa.Persistence.Implementations;
|
||||
using Elsa.Persistence.Services;
|
||||
using Elsa.Services;
|
||||
|
|
@ -7,6 +8,13 @@ namespace Elsa.Persistence.Options;
|
|||
|
||||
public class PersistenceOptions : IConfigurator
|
||||
{
|
||||
public ElsaOptionsConfigurator ElsaOptionsConfigurator { get; }
|
||||
|
||||
public PersistenceOptions(ElsaOptionsConfigurator elsaOptionsConfigurator)
|
||||
{
|
||||
ElsaOptionsConfigurator = elsaOptionsConfigurator;
|
||||
}
|
||||
|
||||
public Func<IServiceProvider, IWorkflowDefinitionStore> WorkflowDefinitionStore { get; set; } = _ => new NullWorkflowDefinitionStore();
|
||||
public Func<IServiceProvider, IWorkflowInstanceStore> WorkflowInstanceStore { get; set; } = _ => new NullWorkflowInstanceStore();
|
||||
public Func<IServiceProvider, IWorkflowBookmarkStore> WorkflowBookmarkStore { get; set; } = _ => new NullWorkflowBookmarkStore();
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ using Elsa.Management.Extensions;
|
|||
using Elsa.Mediator.Extensions;
|
||||
using Elsa.Modules.Activities.Extensions;
|
||||
using Elsa.Options;
|
||||
using Elsa.Persistence.Extensions;
|
||||
using Elsa.Persistence.InMemory.Extensions;
|
||||
using Elsa.Runtime.Extensions;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
|
@ -18,8 +19,8 @@ public static class ServiceCollectionExtensions
|
|||
return services
|
||||
.AddElsaCore(elsa =>
|
||||
{
|
||||
elsa.UseInMemoryPersistence();
|
||||
elsa.AddActivityServices();
|
||||
elsa.UsePersistence(persistence => persistence.UseInMemoryProvider());
|
||||
elsa.UseActivityServices();
|
||||
elsa.AddElsaRuntime();
|
||||
elsa.AddElsaManagement();
|
||||
configure?.Invoke(elsa);
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ public static class ServiceCollectionExtensions
|
|||
/// <summary>
|
||||
/// Registers required services for activities provided by this package.
|
||||
/// </summary>
|
||||
public static ActivityOptions AddActivityServices(this ElsaOptionsConfigurator configurator)
|
||||
public static ActivityOptions UseActivityServices(this ElsaOptionsConfigurator configurator)
|
||||
{
|
||||
return configurator.Configure<ActivityOptions>();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,17 @@
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using Elsa.Persistence.EntityFrameworkCore.Options;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Elsa.Persistence.EntityFrameworkCore.Sqlite
|
||||
{
|
||||
public static class DbContextOptionsBuilderExtensions
|
||||
{
|
||||
public static DbContextOptionsBuilder UseSqlite(this DbContextOptionsBuilder builder, string connectionString = "Data Source=elsa.sqlite.db;Cache=Shared;") => builder.UseSqlite(connectionString, db => db
|
||||
.MigrationsAssembly(typeof(SqliteElsaContextFactory).Assembly.GetName().Name)
|
||||
.MigrationsHistoryTable(ElsaDbContext.MigrationsHistoryTable, ElsaDbContext.ElsaSchema));
|
||||
public static EFCorePersistenceOptions UseSqlite(this EFCorePersistenceOptions builder, string connectionString = "Data Source=elsa.sqlite.db;Cache=Shared;")
|
||||
{
|
||||
builder.ConfigureDbContextOptions((_, x) => x.UseSqlite(connectionString, db => db
|
||||
.MigrationsAssembly(typeof(SqliteElsaContextFactory).Assembly.GetName().Name)
|
||||
.MigrationsHistoryTable(ElsaDbContext.MigrationsHistoryTable, ElsaDbContext.ElsaSchema)));
|
||||
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,57 +1,20 @@
|
|||
using Elsa.Persistence.Entities;
|
||||
using Elsa.Persistence.EntityFrameworkCore.Handlers;
|
||||
using Elsa.Persistence.EntityFrameworkCore.HostedServices;
|
||||
using Elsa.Persistence.EntityFrameworkCore.Implementations;
|
||||
using Elsa.Persistence.EntityFrameworkCore.Services;
|
||||
using Elsa.Persistence.Services;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Elsa.Persistence.EntityFrameworkCore.Options;
|
||||
using Elsa.Persistence.Options;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Elsa.Persistence.EntityFrameworkCore.Extensions;
|
||||
|
||||
public static class ServiceCollectionExtensions
|
||||
{
|
||||
public static IServiceCollection AddEntityFrameworkCorePersistence(
|
||||
this IServiceCollection services,
|
||||
Action<IServiceProvider, DbContextOptionsBuilder> configure,
|
||||
bool useContextPooling = true)
|
||||
public static PersistenceOptions UseEntityFrameworkCoreProvider(this PersistenceOptions configurator, Action<EFCorePersistenceOptions> configure)
|
||||
{
|
||||
services.AddElsaDbContextFactory(configure, useContextPooling);
|
||||
|
||||
services
|
||||
.AddSingleton<IStore<WorkflowDefinition>, EFCoreStore<WorkflowDefinition>>()
|
||||
.AddSingleton<IStore<WorkflowInstance>, EFCoreStore<WorkflowInstance>>()
|
||||
.AddSingleton<IStore<WorkflowBookmark>, EFCoreStore<WorkflowBookmark>>()
|
||||
.AddSingleton<IStore<WorkflowTrigger>, EFCoreStore<WorkflowTrigger>>()
|
||||
.AddSingleton<IStore<WorkflowExecutionLogRecord>, EFCoreStore<WorkflowExecutionLogRecord>>()
|
||||
.AddSingleton<IWorkflowInstanceStore, EFCoreWorkflowInstanceStore>()
|
||||
.AddSingleton<IWorkflowDefinitionStore, EFCoreWorkflowDefinitionStore>()
|
||||
.AddSingleton<IWorkflowTriggerStore, EFCoreWorkflowTriggerStore>()
|
||||
.AddSingleton<IWorkflowBookmarkStore, EFCoreWorkflowBookmarkStore>()
|
||||
.AddSingleton<IWorkflowExecutionLogStore, EFCoreWorkflowExecutionLogStore>()
|
||||
.AddSingleton<IEntitySerializer<WorkflowDefinition>, WorkflowDefinitionSerializer>()
|
||||
.AddSingleton<IEntitySerializer<WorkflowInstance>, WorkflowInstanceSerializer>()
|
||||
.AddSingleton<IEntitySerializer<WorkflowExecutionLogRecord>, WorkflowExecutionLogRecordSerializer>()
|
||||
;
|
||||
|
||||
return services;
|
||||
configurator.ElsaOptionsConfigurator.Configure(() => new EFCorePersistenceOptions(configurator), configure);
|
||||
return configurator;
|
||||
}
|
||||
|
||||
public static IServiceCollection AutoRunMigrations(this IServiceCollection services)
|
||||
{
|
||||
return services.AddHostedService<RunMigrations>();
|
||||
}
|
||||
|
||||
private static IServiceCollection AddElsaDbContextFactory(this IServiceCollection services,
|
||||
Action<IServiceProvider, DbContextOptionsBuilder> configure,
|
||||
bool useContextPooling,
|
||||
ServiceLifetime serviceLifetime = ServiceLifetime.Singleton)
|
||||
{
|
||||
if (useContextPooling)
|
||||
services.AddPooledDbContextFactory<ElsaDbContext>(configure);
|
||||
else
|
||||
services.AddDbContextFactory<ElsaDbContext>(configure, serviceLifetime);
|
||||
|
||||
return services;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
using Elsa.Persistence.Entities;
|
||||
using Elsa.Persistence.EntityFrameworkCore.Handlers;
|
||||
using Elsa.Persistence.EntityFrameworkCore.Implementations;
|
||||
using Elsa.Persistence.EntityFrameworkCore.Services;
|
||||
using Elsa.Persistence.Options;
|
||||
using Elsa.Services;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Elsa.Persistence.EntityFrameworkCore.Options;
|
||||
|
||||
public class EFCorePersistenceOptions : IConfigurator
|
||||
{
|
||||
public EFCorePersistenceOptions(PersistenceOptions persistenceOptions)
|
||||
{
|
||||
PersistenceOptions = persistenceOptions;
|
||||
|
||||
persistenceOptions
|
||||
.WithWorkflowDefinitionStore(sp => sp.GetRequiredService<EFCoreWorkflowDefinitionStore>())
|
||||
.WithWorkflowInstanceStore(sp => sp.GetRequiredService<EFCoreWorkflowInstanceStore>())
|
||||
.WithWorkflowBookmarkStore(sp => sp.GetRequiredService<EFCoreWorkflowBookmarkStore>())
|
||||
.WithWorkflowTriggerStore(sp => sp.GetRequiredService<EFCoreWorkflowTriggerStore>())
|
||||
.WithWorkflowExecutionLogStore(sp => sp.GetRequiredService<EFCoreWorkflowExecutionLogStore>())
|
||||
;
|
||||
}
|
||||
|
||||
public PersistenceOptions PersistenceOptions { get; }
|
||||
public bool ContextPoolingIsEnabled { get; set; }
|
||||
public ServiceLifetime DbContextFactoryLifetime { get; set; } = ServiceLifetime.Singleton;
|
||||
public Action<IServiceProvider, DbContextOptionsBuilder> DbContextOptionsBuilderAction = (_, _) => { };
|
||||
|
||||
public EFCorePersistenceOptions WithContextPooling(bool enabled = true)
|
||||
{
|
||||
ContextPoolingIsEnabled = enabled;
|
||||
return this;
|
||||
}
|
||||
|
||||
public EFCorePersistenceOptions ConfigureDbContextOptions(Action<IServiceProvider, DbContextOptionsBuilder> configure)
|
||||
{
|
||||
DbContextOptionsBuilderAction = configure;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
if (ContextPoolingIsEnabled)
|
||||
services.AddPooledDbContextFactory<ElsaDbContext>(DbContextOptionsBuilderAction);
|
||||
else
|
||||
services.AddDbContextFactory<ElsaDbContext>(DbContextOptionsBuilderAction, DbContextFactoryLifetime);
|
||||
|
||||
services
|
||||
.AddSingleton<IStore<WorkflowDefinition>, EFCoreStore<WorkflowDefinition>>()
|
||||
.AddSingleton<IStore<WorkflowInstance>, EFCoreStore<WorkflowInstance>>()
|
||||
.AddSingleton<IStore<WorkflowBookmark>, EFCoreStore<WorkflowBookmark>>()
|
||||
.AddSingleton<IStore<WorkflowTrigger>, EFCoreStore<WorkflowTrigger>>()
|
||||
.AddSingleton<IStore<WorkflowExecutionLogRecord>, EFCoreStore<WorkflowExecutionLogRecord>>()
|
||||
.AddSingleton<EFCoreWorkflowInstanceStore>()
|
||||
.AddSingleton<EFCoreWorkflowDefinitionStore>()
|
||||
.AddSingleton<EFCoreWorkflowTriggerStore>()
|
||||
.AddSingleton<EFCoreWorkflowBookmarkStore>()
|
||||
.AddSingleton<EFCoreWorkflowExecutionLogStore>()
|
||||
.AddSingleton<IEntitySerializer<WorkflowDefinition>, WorkflowDefinitionSerializer>()
|
||||
.AddSingleton<IEntitySerializer<WorkflowInstance>, WorkflowInstanceSerializer>()
|
||||
.AddSingleton<IEntitySerializer<WorkflowExecutionLogRecord>, WorkflowExecutionLogRecordSerializer>()
|
||||
;
|
||||
}
|
||||
}
|
||||
|
|
@ -10,9 +10,9 @@ namespace Elsa.Persistence.InMemory.Extensions;
|
|||
|
||||
public static class ServiceCollectionExtensions
|
||||
{
|
||||
public static PersistenceOptions UseInMemoryPersistence(this ElsaOptionsConfigurator configurator)
|
||||
public static PersistenceOptions UseInMemoryProvider(this PersistenceOptions configurator)
|
||||
{
|
||||
var services = configurator.Services;
|
||||
var services = configurator.ElsaOptionsConfigurator.Services;
|
||||
|
||||
services
|
||||
.AddSingleton<InMemoryStore<WorkflowDefinition>>()
|
||||
|
|
@ -27,12 +27,12 @@ public static class ServiceCollectionExtensions
|
|||
.AddSingleton<InMemoryWorkflowExecutionLogStore>()
|
||||
;
|
||||
|
||||
return configurator.Configure<PersistenceOptions>()
|
||||
return configurator.ElsaOptionsConfigurator.Configure(() => new PersistenceOptions(configurator.ElsaOptionsConfigurator), o => o
|
||||
.WithWorkflowDefinitionStore(sp => sp.GetRequiredService<InMemoryWorkflowDefinitionStore>())
|
||||
.WithWorkflowInstanceStore(sp => sp.GetRequiredService<InMemoryWorkflowInstanceStore>())
|
||||
.WithWorkflowBookmarkStore(sp => sp.GetRequiredService<InMemoryWorkflowBookmarkStore>())
|
||||
.WithWorkflowTriggerStore(sp => sp.GetRequiredService<InMemoryWorkflowTriggerStore>())
|
||||
.WithWorkflowExecutionLogStore(sp => sp.GetRequiredService<InMemoryWorkflowExecutionLogStore>())
|
||||
.WithWorkflowExecutionLogStore(sp => sp.GetRequiredService<InMemoryWorkflowExecutionLogStore>()))
|
||||
;
|
||||
}
|
||||
}
|
||||
|
|
@ -16,6 +16,7 @@ using Elsa.Modules.Scheduling.Extensions;
|
|||
using Elsa.Modules.WorkflowContexts.Extensions;
|
||||
using Elsa.Persistence.EntityFrameworkCore.Extensions;
|
||||
using Elsa.Persistence.EntityFrameworkCore.Sqlite;
|
||||
using Elsa.Persistence.Extensions;
|
||||
using Elsa.Pipelines.WorkflowExecution.Components;
|
||||
using Elsa.Runtime.Extensions;
|
||||
using Elsa.Samples.Web1.Activities;
|
||||
|
|
@ -40,9 +41,8 @@ var sqlServerConnectionString = configuration.GetConnectionString("SqlServer");
|
|||
// Add services.
|
||||
services
|
||||
.AutoRunMigrations()
|
||||
.AddElsa()
|
||||
.AddElsa(elsa => elsa.UsePersistence(p => p.UseEntityFrameworkCoreProvider(ef => ef.UseSqlite())))
|
||||
//.AddProtoActorWorkflowHost()
|
||||
.AddEntityFrameworkCorePersistence((_, ef) => ef.UseSqlite())
|
||||
.AddJobServices(new QuartzJobSchedulerProvider(), new HangfireJobQueueProvider())
|
||||
.AddSchedulingServices()
|
||||
.AddHttpActivityServices()
|
||||
|
|
|
|||
|
|
@ -94,7 +94,8 @@ class Program
|
|||
var services = new ServiceCollection();
|
||||
|
||||
services
|
||||
.AddElsa(elsa => elsa.Configure<ActivityOptions>().WithStandardOutStreamProvider(sp => new CustomOutStreamProvider(Console.Out)))
|
||||
.AddElsa(elsa => elsa.Configure<ActivityOptions>()
|
||||
.WithStandardOutStreamProvider(sp => new CustomOutStreamProvider(Console.Out)))
|
||||
.AddLogging(logging => logging.AddConsole().SetMinimumLevel(LogLevel.Warning));
|
||||
|
||||
return services.BuildServiceProvider();
|
||||
|
|
|
|||
Loading…
Reference in a new issue