< Summary

Information
Class: Elsa.Persistence.EFCore.PersistenceFeatureBase<T1, T2>
Assembly: Elsa.Persistence.EFCore.Common
File(s): /home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Persistence.EFCore.Common/PersistenceFeatureBase.cs
Line coverage
94%
Covered lines: 35
Uncovered lines: 2
Coverable lines: 37
Total lines: 99
Line coverage: 94.5%
Branch coverage
50%
Covered branches: 2
Total branches: 4
Branch coverage: 50%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
get_UseContextPooling()100%11100%
get_RunMigrations()100%11100%
get_DbContextFactoryLifetime()100%11100%
get_DbContextOptionsBuilder()100%11100%
ConfigureHostedServices()100%11100%
Apply()50%4488.88%
ConfigureMigrations()100%11100%
AddStore()100%11100%
AddEntityStore()100%11100%

File(s)

/home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Persistence.EFCore.Common/PersistenceFeatureBase.cs

#LineLine coverage
 1using Elsa.Common.Entities;
 2using Elsa.Extensions;
 3using Elsa.Features.Abstractions;
 4using Elsa.Features.Services;
 5using Elsa.Persistence.EFCore.EntityHandlers;
 6using Microsoft.EntityFrameworkCore;
 7using Microsoft.EntityFrameworkCore.Diagnostics;
 8using Microsoft.Extensions.DependencyInjection;
 9
 10// ReSharper disable once CheckNamespace
 11namespace Elsa.Persistence.EFCore;
 12
 4213public abstract class PersistenceFeatureBase<TFeature, TDbContext>(IModule module) : FeatureBase(module)
 14    where TDbContext : ElsaDbContextBase
 15{
 16    /// <summary>
 17    /// Gets or sets a value indicating whether to use context pooling.
 18    /// </summary>
 4219    public virtual bool UseContextPooling { get; set; }
 20
 21    /// <summary>
 22    /// Gets or sets a value indicating whether to run migrations.
 23    /// </summary>
 8424    public virtual bool RunMigrations { get; set; } = true;
 25
 26    /// <summary>
 27    /// Gets or sets the lifetime of the <see cref="IDbContextFactory{TContext}"/>. Defaults to <see cref="ServiceLifeti
 28    /// </summary>
 8429    public ServiceLifetime DbContextFactoryLifetime { get; set; } = ServiceLifetime.Scoped;
 30
 31    /// <summary>
 32    /// Gets or sets the callback used to configure the <see cref="DbContextOptionsBuilder"/>.
 33    /// </summary>
 316334    public virtual Action<IServiceProvider, DbContextOptionsBuilder> DbContextOptionsBuilder { get; set; } = null!;
 35
 36    public override void ConfigureHostedServices()
 37    {
 4238        ConfigureMigrations();
 4239    }
 40
 41    /// <inheritdoc />
 42    public override void Apply()
 43    {
 4244        if (DbContextOptionsBuilder == null)
 045            throw new InvalidOperationException("The DbContextOptionsBuilder must be configured.");
 46
 4247        Action<IServiceProvider, DbContextOptionsBuilder> setup = (sp, opts) =>
 4248        {
 610249            opts.ConfigureWarnings(w => w.Ignore(RelationalEventId.PendingModelChangesWarning));
 305150            DbContextOptionsBuilder(sp, opts);
 309351        };
 52
 4253        if (UseContextPooling)
 054            Services.AddPooledDbContextFactory<TDbContext>(setup);
 55        else
 4256            Services.AddDbContextFactory<TDbContext>(setup, DbContextFactoryLifetime);
 57
 4258        Services.Decorate<IDbContextFactory<TDbContext>, TenantAwareDbContextFactory<TDbContext>>();
 59
 4260        Services.Configure<MigrationOptions>(options =>
 4261        {
 4262            options.RunMigrations[typeof(TDbContext)] = RunMigrations;
 8463        });
 64
 4265        Services.AddScoped<IEntitySavingHandler, ApplyTenantId>();
 4266        Services.AddScoped<IEntityModelCreatingHandler, SetTenantIdFilter>();
 4267    }
 68
 69    protected virtual void ConfigureMigrations()
 70    {
 4271        Services.AddStartupTask<RunMigrationsStartupTask<TDbContext>>();
 4272    }
 73
 74    /// <summary>
 75    /// Adds a store to the service collection.
 76    /// </summary>
 77    /// <typeparam name="TEntity">The type of the entity.</typeparam>
 78    /// <typeparam name="TStore">The type of the store.</typeparam>
 79    protected void AddStore<TEntity, TStore>() where TEntity : class, new() where TStore : class
 80    {
 2181        Services
 2182            .AddScoped<Store<TDbContext, TEntity>>()
 2183            .AddScoped<TStore>()
 2184            ;
 2185    }
 86
 87    /// <summary>
 88    /// Adds an entity store to the service collection.
 89    /// </summary>
 90    /// <typeparam name="TEntity">The type of the entity.</typeparam>
 91    /// <typeparam name="TStore">The type of the store.</typeparam>
 92    protected void AddEntityStore<TEntity, TStore>() where TEntity : Entity, new() where TStore : class
 93    {
 7094        Services
 7095            .AddScoped<EntityStore<TDbContext, TEntity>>()
 7096            .AddScoped<TStore>()
 7097            ;
 7098    }
 99}