Extract reusable base store

This commit is contained in:
Sipke Schoorstra 2021-05-28 12:12:00 +02:00
parent da8d12b9e4
commit 7b0bf355f8
10 changed files with 36 additions and 17 deletions

View file

@ -8,7 +8,7 @@ namespace Elsa.Persistence.EntityFramework.Core.Extensions
{
public static class QueryableBulkExtensions
{
public static async Task<int> BatchDeleteWithWorkAroundAsync<T>(this IQueryable<T> queryable, ElsaContext elsaContext, CancellationToken cancellationToken = default) where T : class
public static async Task<int> BatchDeleteWithWorkAroundAsync<T>(this IQueryable<T> queryable, DbContext elsaContext, CancellationToken cancellationToken = default) where T : class
{
if (elsaContext.Database.IsPostgres())
{

View file

@ -2,7 +2,7 @@ using Microsoft.EntityFrameworkCore;
namespace Elsa.Persistence.EntityFramework.Core.Services
{
public class ElsaContextFactory<TElsaContext> : IElsaContextFactory where TElsaContext:ElsaContext
public class ElsaContextFactory<TElsaContext> : IElsaContextFactory where TElsaContext : ElsaContext
{
private readonly IDbContextFactory<TElsaContext> _contextFactory;
public ElsaContextFactory(IDbContextFactory<TElsaContext> contextFactory) => _contextFactory = contextFactory;

View file

@ -0,0 +1,7 @@
namespace Elsa.Persistence.EntityFramework.Core.Services
{
public interface IContextFactory<out TContext>
{
TContext CreateDbContext();
}
}

View file

@ -1,7 +1,6 @@
namespace Elsa.Persistence.EntityFramework.Core.Services
{
public interface IElsaContextFactory
public interface IElsaContextFactory : IContextFactory<ElsaContext>
{
ElsaContext CreateDbContext();
}
}

View file

@ -0,0 +1,13 @@
using AutoMapper;
using Elsa.Models;
using Elsa.Persistence.EntityFramework.Core.Services;
namespace Elsa.Persistence.EntityFramework.Core.Stores
{
public abstract class ElsaContextEntityFrameworkStore<T> : EntityFrameworkStore<T, ElsaContext> where T : class, IEntity
{
protected ElsaContextEntityFrameworkStore(IContextFactory<ElsaContext> dbContextFactory, IMapper mapper) : base(dbContextFactory, mapper)
{
}
}
}

View file

@ -7,7 +7,7 @@ using Elsa.Persistence.Specifications;
namespace Elsa.Persistence.EntityFramework.Core.Stores
{
public class EntityFrameworkBookmarkStore : EntityFrameworkStore<Bookmark>, IBookmarkStore
public class EntityFrameworkBookmarkStore : ElsaContextEntityFrameworkStore<Bookmark>, IBookmarkStore
{
public EntityFrameworkBookmarkStore(IElsaContextFactory dbContextFactory, IMapper mapper) : base(dbContextFactory, mapper)
{

View file

@ -13,18 +13,18 @@ using Microsoft.EntityFrameworkCore;
namespace Elsa.Persistence.EntityFramework.Core.Stores
{
public abstract class EntityFrameworkStore<T> : IStore<T> where T : class, IEntity
public abstract class EntityFrameworkStore<T, TContext> : IStore<T> where T : class, IEntity where TContext:DbContext
{
private readonly IMapper _mapper;
private readonly SemaphoreSlim _semaphore = new(1);
protected EntityFrameworkStore(IElsaContextFactory dbContextFactory, IMapper mapper)
protected EntityFrameworkStore(IContextFactory<TContext> dbContextFactory, IMapper mapper)
{
_mapper = mapper;
DbContextFactory = dbContextFactory;
}
protected IElsaContextFactory DbContextFactory { get; }
protected IContextFactory<TContext> DbContextFactory { get; }
public async Task SaveAsync(T entity, CancellationToken cancellationToken)
{
@ -126,7 +126,7 @@ namespace Elsa.Persistence.EntityFramework.Core.Stores
}, cancellationToken);
}
private T ReadShadowProperties(ElsaContext dbContext, T entity)
private T ReadShadowProperties(TContext dbContext, T entity)
{
OnLoading(dbContext, entity);
return entity;
@ -150,14 +150,14 @@ namespace Elsa.Persistence.EntityFramework.Core.Stores
protected ValueTask<TResult> DoWorkOnSet<TResult>(Func<DbSet<T>, ValueTask<TResult>> work, CancellationToken cancellationToken) => DoWork(dbContext => work(dbContext.Set<T>()), cancellationToken);
protected ValueTask DoWorkOnSet(Action<DbSet<T>> work, CancellationToken cancellationToken) => DoWork(dbContext => work(dbContext.Set<T>()), cancellationToken);
protected async ValueTask DoWork(Func<ElsaContext, ValueTask> work, CancellationToken cancellationToken)
protected async ValueTask DoWork(Func<TContext, ValueTask> work, CancellationToken cancellationToken)
{
await using var dbContext = DbContextFactory.CreateDbContext();
await work(dbContext);
await dbContext.SaveChangesAsync(cancellationToken);
}
protected async ValueTask<TResult> DoWork<TResult>(Func<ElsaContext, ValueTask<TResult>> work, CancellationToken cancellationToken)
protected async ValueTask<TResult> DoWork<TResult>(Func<TContext, ValueTask<TResult>> work, CancellationToken cancellationToken)
{
await using var dbContext = DbContextFactory.CreateDbContext();
var result = await work(dbContext);
@ -165,20 +165,20 @@ namespace Elsa.Persistence.EntityFramework.Core.Stores
return result;
}
protected async ValueTask DoWork(Action<ElsaContext> work, CancellationToken cancellationToken)
protected async ValueTask DoWork(Action<TContext> work, CancellationToken cancellationToken)
{
await using var dbContext = DbContextFactory.CreateDbContext();
work(dbContext);
await dbContext.SaveChangesAsync(cancellationToken);
}
protected virtual void OnSaving(ElsaContext dbContext, T entity) => OnSaving(entity);
protected virtual void OnSaving(TContext dbContext, T entity) => OnSaving(entity);
protected virtual void OnSaving(T entity)
{
}
protected virtual void OnLoading(ElsaContext dbContext, T entity) => OnLoading(entity);
protected virtual void OnLoading(TContext dbContext, T entity) => OnLoading(entity);
protected virtual void OnLoading(T entity)
{

View file

@ -9,7 +9,7 @@ using Newtonsoft.Json;
namespace Elsa.Persistence.EntityFramework.Core.Stores
{
public class EntityFrameworkWorkflowDefinitionStore : EntityFrameworkStore<WorkflowDefinition>, IWorkflowDefinitionStore
public class EntityFrameworkWorkflowDefinitionStore : ElsaContextEntityFrameworkStore<WorkflowDefinition>, IWorkflowDefinitionStore
{
private readonly IContentSerializer _contentSerializer;

View file

@ -7,7 +7,7 @@ using Elsa.Persistence.Specifications;
namespace Elsa.Persistence.EntityFramework.Core.Stores
{
public class EntityFrameworkWorkflowExecutionLogRecordStore : EntityFrameworkStore<WorkflowExecutionLogRecord>, IWorkflowExecutionLogStore
public class EntityFrameworkWorkflowExecutionLogRecordStore : ElsaContextEntityFrameworkStore<WorkflowExecutionLogRecord>, IWorkflowExecutionLogStore
{
public EntityFrameworkWorkflowExecutionLogRecordStore(IElsaContextFactory dbContextFactory, IMapper mapper) : base(dbContextFactory, mapper)
{

View file

@ -13,7 +13,7 @@ using Newtonsoft.Json;
namespace Elsa.Persistence.EntityFramework.Core.Stores
{
public class EntityFrameworkWorkflowInstanceStore : EntityFrameworkStore<WorkflowInstance>, IWorkflowInstanceStore
public class EntityFrameworkWorkflowInstanceStore : ElsaContextEntityFrameworkStore<WorkflowInstance>, IWorkflowInstanceStore
{
private readonly IContentSerializer _contentSerializer;