From 92b3e3e324918b22464dde7161be7ca2afb05291 Mon Sep 17 00:00:00 2001 From: Salih Date: Thu, 7 Mar 2024 13:40:27 +0300 Subject: [PATCH] Allow extending ConfigureConventions and OnModelCreating --- .../Abp/EntityFrameworkCore/AbpDbContext.cs | 50 +++++++++++++++ .../AbpDbContextOptions.cs | 63 ++++++++++++++++++- 2 files changed, 112 insertions(+), 1 deletion(-) diff --git a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs index b06ba191dd..de38a8bbf8 100644 --- a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs +++ b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs @@ -14,6 +14,7 @@ using Microsoft.EntityFrameworkCore.ChangeTracking; using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; +using Microsoft.Extensions.Options; using Volo.Abp.Auditing; using Volo.Abp.Data; using Volo.Abp.DependencyInjection; @@ -115,6 +116,55 @@ public abstract class AbpDbContext : DbContext, IAbpEfCoreDbContext, .MakeGenericMethod(entityType.ClrType) .Invoke(this, new object[] { modelBuilder, entityType }); } + + var abpDbContextOptions = LazyServiceProvider.LazyGetRequiredService>().Value; + + var modelBuilderActions = abpDbContextOptions.ModelBuilderActions.GetOrDefault(typeof(TDbContext)); + if(modelBuilderActions == null) + { + return; + } + var actions = modelBuilderActions.OrderBy(a => a.Key).Select(a => a.Value).ToList(); + foreach (var action in actions) + { + if(action is Action modelBuilderAction) + { + modelBuilderAction.Invoke(modelBuilder, this); + } + + if(this is TDbContext dbContext && action is Action dbContextAction) + { + dbContextAction.Invoke(modelBuilder, dbContext); + } + } + } + + protected override void ConfigureConventions(ModelConfigurationBuilder configurationBuilder) + { + base.ConfigureConventions(configurationBuilder); + + var abpDbContextOptions = LazyServiceProvider.LazyGetRequiredService>().Value; + var conventions = abpDbContextOptions.Conventions.GetOrDefault(typeof(TDbContext)); + + if(conventions == null) + { + return; + } + + var actions = conventions.OrderBy(a => a.Key).Select(a => a.Value).ToList(); + + foreach (var action in actions) + { + if(action is Action modelBuilderAction) + { + modelBuilderAction.Invoke(configurationBuilder, this); + } + + if(this is TDbContext dbContext && action is Action dbContextAction) + { + dbContextAction.Invoke(configurationBuilder, dbContext); + } + } } protected virtual void TrySetDatabaseProvider(ModelBuilder modelBuilder) diff --git a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContextOptions.cs b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContextOptions.cs index cb5b258192..93de6a473c 100644 --- a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContextOptions.cs +++ b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContextOptions.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using JetBrains.Annotations; +using Microsoft.EntityFrameworkCore; using Volo.Abp.DependencyInjection; using Volo.Abp.EntityFrameworkCore.DependencyInjection; using Volo.Abp.MultiTenancy; @@ -20,12 +21,18 @@ public class AbpDbContextOptions internal Dictionary DbContextReplacements { get; } + internal Dictionary>> Conventions { get; } + + internal Dictionary>> ModelBuilderActions { get; } + public AbpDbContextOptions() { DefaultPreConfigureActions = new List>(); PreConfigureActions = new Dictionary>(); ConfigureActions = new Dictionary(); DbContextReplacements = new Dictionary(); + Conventions = new Dictionary>>(); + ModelBuilderActions = new Dictionary>>(); } public void PreConfigure([NotNull] Action action) @@ -41,6 +48,60 @@ public class AbpDbContextOptions DefaultConfigureAction = action; } + + public void ConfigureConventions([NotNull] Action action, Type? dbContextType = null, int? order = null) + { + Check.NotNull(action, nameof(action)); + + var actions = Conventions.GetOrDefault(dbContextType ?? typeof(AbpDbContext<>)); + if (actions == null) + { + Conventions[dbContextType ?? typeof(AbpDbContext<>)] = actions = new List>(); + } + + actions.Add(new KeyValuePair(order, action)); + } + + public void ConfigureConventions([NotNull] Action action, int? order = null) + where TDbContext : AbpDbContext + { + Check.NotNull(action, nameof(action)); + + var actions = Conventions.GetOrDefault(typeof(TDbContext)); + if (actions == null) + { + Conventions[typeof(TDbContext)] = actions = new List>(); + } + + actions.Add(new KeyValuePair(order, action)); + } + + public void OnModelCreating([NotNull] Action action, Type? dbContextType = null, int? order = null) + { + Check.NotNull(action, nameof(action)); + + var actions = ModelBuilderActions.GetOrDefault(dbContextType ?? typeof(AbpDbContext<>)); + if (actions == null) + { + ModelBuilderActions[dbContextType ?? typeof(AbpDbContext<>)] = actions = new List>(); + } + + actions.Add(new KeyValuePair(order, action)); + } + + public void OnModelCreating([NotNull] Action action, int? order = null) + where TDbContext : AbpDbContext + { + Check.NotNull(action, nameof(action)); + + var actions = ModelBuilderActions.GetOrDefault(typeof(TDbContext)); + if (actions == null) + { + ModelBuilderActions[typeof(TDbContext)] = actions = new List>(); + } + + actions.Add(new KeyValuePair(order, action)); + } public bool IsConfiguredDefault() { @@ -102,4 +163,4 @@ public class AbpDbContextOptions } } } -} +} \ No newline at end of file