< 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
 1813public 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>
 1819    public virtual bool UseContextPooling { get; set; }
 20
 21    /// <summary>
 22    /// Gets or sets a value indicating whether to run migrations.
 23    /// </summary>
 3624    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>
 3629    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>
 242934    public virtual Action<IServiceProvider, DbContextOptionsBuilder> DbContextOptionsBuilder { get; set; } = null!;
 35
 36    public override void ConfigureHostedServices()
 37    {
 1838        ConfigureMigrations();
 1839    }
 40
 41    /// <inheritdoc />
 42    public override void Apply()
 43    {
 1844        if (DbContextOptionsBuilder == null)
 045            throw new InvalidOperationException("The DbContextOptionsBuilder must be configured.");
 46
 1847        Action<IServiceProvider, DbContextOptionsBuilder> setup = (sp, opts) =>
 1848        {
 476249            opts.ConfigureWarnings(w => w.Ignore(RelationalEventId.PendingModelChangesWarning));
 238150            DbContextOptionsBuilder(sp, opts);
 239951        };
 52
 1853        if (UseContextPooling)
 054            Services.AddPooledDbContextFactory<TDbContext>(setup);
 55        else
 1856            Services.AddDbContextFactory<TDbContext>(setup, DbContextFactoryLifetime);
 57
 1858        Services.Decorate<IDbContextFactory<TDbContext>, TenantAwareDbContextFactory<TDbContext>>();
 59
 1860        Services.Configure<MigrationOptions>(options =>
 1861        {
 1862            options.RunMigrations[typeof(TDbContext)] = RunMigrations;
 3663        });
 64
 1865        Services.AddScoped<IEntitySavingHandler, ApplyTenantId>();
 1866        Services.AddScoped<IEntityModelCreatingHandler, SetTenantIdFilter>();
 1867    }
 68
 69    protected virtual void ConfigureMigrations()
 70    {
 1871        Services.AddStartupTask<RunMigrationsStartupTask<TDbContext>>();
 1872    }
 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    {
 981        Services
 982            .AddScoped<Store<TDbContext, TEntity>>()
 983            .AddScoped<TStore>()
 984            ;
 985    }
 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    {
 3094        Services
 3095            .AddScoped<EntityStore<TDbContext, TEntity>>()
 3096            .AddScoped<TStore>()
 3097            ;
 3098    }
 99}