From 9ed202e0b7ea4dfaf03da383403bd67fffc5b9a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Fri, 5 Jan 2018 20:56:11 +0300 Subject: [PATCH 1/3] Created IEfCoreDbContext --- .../Abp/EntityFrameworkCore/AbpDbContext.cs | 2 +- .../EntityFrameworkCore/IEfCoreDbContext.cs | 14 +++++++++ .../MultiTenantConnectionStringResolver.cs | 4 +-- .../IMultiTenancyDbContext.cs | 12 +++++++ .../MultiTenancyDbContext.cs | 25 ++------------- ...TenancyDbContextModelCreatingExtensions.cs | 31 +++++++++++++++++++ 6 files changed, 62 insertions(+), 26 deletions(-) create mode 100644 src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/IEfCoreDbContext.cs rename src/Volo.Abp.MultiTenancy.Domain/Volo/Abp/{Data => }/MultiTenancy/MultiTenantConnectionStringResolver.cs (96%) create mode 100644 src/Volo.Abp.MultiTenancy.EntityFrameworkCore/Volo/Abp/MultiTenancy/EntityFrameworkCore/IMultiTenancyDbContext.cs create mode 100644 src/Volo.Abp.MultiTenancy.EntityFrameworkCore/Volo/Abp/MultiTenancy/EntityFrameworkCore/MultiTenancyDbContextModelCreatingExtensions.cs diff --git a/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs b/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs index 07bc3f6760..4b2edcc6dc 100644 --- a/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs +++ b/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs @@ -17,7 +17,7 @@ using Volo.Abp.Uow; namespace Volo.Abp.EntityFrameworkCore { - public abstract class AbpDbContext : DbContext + public abstract class AbpDbContext : DbContext, IEfCoreDbContext where TDbContext : DbContext { public Guid? CurrentTenantId => CurrentTenant?.Id; diff --git a/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/IEfCoreDbContext.cs b/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/IEfCoreDbContext.cs new file mode 100644 index 0000000000..880d4112e3 --- /dev/null +++ b/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/IEfCoreDbContext.cs @@ -0,0 +1,14 @@ +using Microsoft.EntityFrameworkCore; + +namespace Volo.Abp.EntityFrameworkCore +{ + public interface IEfCoreDbContext + { + int SaveChanges(); + + int SaveChanges(bool acceptAllChangesOnSuccess); + + DbSet Set() + where T: class; + } +} diff --git a/src/Volo.Abp.MultiTenancy.Domain/Volo/Abp/Data/MultiTenancy/MultiTenantConnectionStringResolver.cs b/src/Volo.Abp.MultiTenancy.Domain/Volo/Abp/MultiTenancy/MultiTenantConnectionStringResolver.cs similarity index 96% rename from src/Volo.Abp.MultiTenancy.Domain/Volo/Abp/Data/MultiTenancy/MultiTenantConnectionStringResolver.cs rename to src/Volo.Abp.MultiTenancy.Domain/Volo/Abp/MultiTenancy/MultiTenantConnectionStringResolver.cs index 659f9cf9d1..8eebb45ef4 100644 --- a/src/Volo.Abp.MultiTenancy.Domain/Volo/Abp/Data/MultiTenancy/MultiTenantConnectionStringResolver.cs +++ b/src/Volo.Abp.MultiTenancy.Domain/Volo/Abp/MultiTenancy/MultiTenantConnectionStringResolver.cs @@ -1,9 +1,9 @@ using System.Collections.Generic; using Microsoft.Extensions.Options; +using Volo.Abp.Data; using Volo.Abp.DependencyInjection; -using Volo.Abp.MultiTenancy; -namespace Volo.Abp.Data.MultiTenancy +namespace Volo.Abp.MultiTenancy { [Dependency(ReplaceServices = true)] public class MultiTenantConnectionStringResolver : DefaultConnectionStringResolver diff --git a/src/Volo.Abp.MultiTenancy.EntityFrameworkCore/Volo/Abp/MultiTenancy/EntityFrameworkCore/IMultiTenancyDbContext.cs b/src/Volo.Abp.MultiTenancy.EntityFrameworkCore/Volo/Abp/MultiTenancy/EntityFrameworkCore/IMultiTenancyDbContext.cs new file mode 100644 index 0000000000..28cf9cd9b7 --- /dev/null +++ b/src/Volo.Abp.MultiTenancy.EntityFrameworkCore/Volo/Abp/MultiTenancy/EntityFrameworkCore/IMultiTenancyDbContext.cs @@ -0,0 +1,12 @@ +using Microsoft.EntityFrameworkCore; +using Volo.Abp.EntityFrameworkCore; + +namespace Volo.Abp.MultiTenancy.EntityFrameworkCore +{ + public interface IMultiTenancyDbContext : IEfCoreDbContext + { + DbSet Tenants { get; set; } + + DbSet TenantConnectionStrings { get; set; } + } +} \ No newline at end of file diff --git a/src/Volo.Abp.MultiTenancy.EntityFrameworkCore/Volo/Abp/MultiTenancy/EntityFrameworkCore/MultiTenancyDbContext.cs b/src/Volo.Abp.MultiTenancy.EntityFrameworkCore/Volo/Abp/MultiTenancy/EntityFrameworkCore/MultiTenancyDbContext.cs index 0dc023ad9f..8648083e31 100644 --- a/src/Volo.Abp.MultiTenancy.EntityFrameworkCore/Volo/Abp/MultiTenancy/EntityFrameworkCore/MultiTenancyDbContext.cs +++ b/src/Volo.Abp.MultiTenancy.EntityFrameworkCore/Volo/Abp/MultiTenancy/EntityFrameworkCore/MultiTenancyDbContext.cs @@ -3,7 +3,7 @@ using Volo.Abp.EntityFrameworkCore; namespace Volo.Abp.MultiTenancy.EntityFrameworkCore { - public class MultiTenancyDbContext : AbpDbContext + public class MultiTenancyDbContext : AbpDbContext, IMultiTenancyDbContext { public DbSet Tenants { get; set; } @@ -18,28 +18,7 @@ namespace Volo.Abp.MultiTenancy.EntityFrameworkCore { base.OnModelCreating(builder); - //TODO: Split configuration to dedicated classes (probably a resuable extension method) - - builder.Entity(b => - { - b.ToTable("MtTenants"); //TODO: Make all table and schema names changeable - - b.Property(t => t.Name).IsRequired().HasMaxLength(TenantConsts.MaxNameLength); - - b.HasMany(u => u.ConnectionStrings).WithOne().HasForeignKey(uc => uc.TenantId).IsRequired(); - - b.HasIndex(u => u.Name); - }); - - builder.Entity(b => - { - b.ToTable("MtTenantConnectionStrings"); - - b.Property(cs => cs.Name).IsRequired().HasMaxLength(TenantConnectionStringConsts.MaxNameLength); - b.Property(cs => cs.Value).IsRequired().HasMaxLength(TenantConnectionStringConsts.MaxValueLength); - - b.HasIndex(cs => cs.TenantId); - }); + this.ConfigureAbpMultiTenancy(builder); } } } diff --git a/src/Volo.Abp.MultiTenancy.EntityFrameworkCore/Volo/Abp/MultiTenancy/EntityFrameworkCore/MultiTenancyDbContextModelCreatingExtensions.cs b/src/Volo.Abp.MultiTenancy.EntityFrameworkCore/Volo/Abp/MultiTenancy/EntityFrameworkCore/MultiTenancyDbContextModelCreatingExtensions.cs new file mode 100644 index 0000000000..c61b9368a4 --- /dev/null +++ b/src/Volo.Abp.MultiTenancy.EntityFrameworkCore/Volo/Abp/MultiTenancy/EntityFrameworkCore/MultiTenancyDbContextModelCreatingExtensions.cs @@ -0,0 +1,31 @@ +using Microsoft.EntityFrameworkCore; + +namespace Volo.Abp.MultiTenancy.EntityFrameworkCore +{ + public static class MultiTenancyDbContextModelCreatingExtensions + { + public static void ConfigureAbpMultiTenancy(this IMultiTenancyDbContext dbContext, ModelBuilder builder) + { + builder.Entity(b => + { + b.ToTable("MtTenants"); //TODO: Make all table and schema names changeable + + b.Property(t => t.Name).IsRequired().HasMaxLength(TenantConsts.MaxNameLength); + + b.HasMany(u => u.ConnectionStrings).WithOne().HasForeignKey(uc => uc.TenantId).IsRequired(); + + b.HasIndex(u => u.Name); + }); + + builder.Entity(b => + { + b.ToTable("MtTenantConnectionStrings"); + + b.Property(cs => cs.Name).IsRequired().HasMaxLength(TenantConnectionStringConsts.MaxNameLength); + b.Property(cs => cs.Value).IsRequired().HasMaxLength(TenantConnectionStringConsts.MaxValueLength); + + b.HasIndex(cs => cs.TenantId); + }); + } + } +} \ No newline at end of file From a5000e99a6f6eaa7042d6f080ad23008207f395e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Fri, 5 Jan 2018 21:46:24 +0300 Subject: [PATCH 2/3] Implemented IEfCoreDbContext everywhere. --- .../AbpDesk.EntityFrameworkCore.csproj | 1 + .../EntityFrameworkCore/AbpDeskDbContext.cs | 10 +- .../AbpDeskEntityFrameworkCoreModule.cs | 7 +- ...184326_MultiTenancyModuleAdded.Designer.cs | 92 +++++++++++++++++++ .../20180105184326_MultiTenancyModuleAdded.cs | 63 +++++++++++++ .../AbpDeskDbContextModelSnapshot.cs | 58 +++++++++++- .../AbpEfCoreServiceCollectionExtensions.cs | 4 +- .../EntityFrameworkCore/EfCoreRepository.cs | 6 +- .../AbpDbContextRegistrationOptions.cs | 1 - .../EntityFrameworkCore/IDbContextProvider.cs | 2 +- .../EntityFrameworkCore/IEfCoreDbContext.cs | 76 ++++++++++++++- .../EntityFrameworkCore/EfCoreDatabaseApi.cs | 2 +- .../EfCoreTransactionApi.cs | 11 ++- .../UnitOfWorkDbContextProvider.cs | 4 +- ...bpMultiTenancyEntityFrameworkCoreModule.cs | 5 + 15 files changed, 322 insertions(+), 20 deletions(-) create mode 100644 src/AbpDesk/AbpDesk.EntityFrameworkCore/Migrations/20180105184326_MultiTenancyModuleAdded.Designer.cs create mode 100644 src/AbpDesk/AbpDesk.EntityFrameworkCore/Migrations/20180105184326_MultiTenancyModuleAdded.cs diff --git a/src/AbpDesk/AbpDesk.EntityFrameworkCore/AbpDesk.EntityFrameworkCore.csproj b/src/AbpDesk/AbpDesk.EntityFrameworkCore/AbpDesk.EntityFrameworkCore.csproj index 857a6a409c..9a42aec87b 100644 --- a/src/AbpDesk/AbpDesk.EntityFrameworkCore/AbpDesk.EntityFrameworkCore.csproj +++ b/src/AbpDesk/AbpDesk.EntityFrameworkCore/AbpDesk.EntityFrameworkCore.csproj @@ -12,6 +12,7 @@ + diff --git a/src/AbpDesk/AbpDesk.EntityFrameworkCore/AbpDesk/EntityFrameworkCore/AbpDeskDbContext.cs b/src/AbpDesk/AbpDesk.EntityFrameworkCore/AbpDesk/EntityFrameworkCore/AbpDeskDbContext.cs index b523edddc9..82e3e582b0 100644 --- a/src/AbpDesk/AbpDesk.EntityFrameworkCore/AbpDesk/EntityFrameworkCore/AbpDeskDbContext.cs +++ b/src/AbpDesk/AbpDesk.EntityFrameworkCore/AbpDesk/EntityFrameworkCore/AbpDeskDbContext.cs @@ -2,14 +2,20 @@ using Microsoft.EntityFrameworkCore; using Volo.Abp.Data; using Volo.Abp.EntityFrameworkCore; +using Volo.Abp.MultiTenancy; +using Volo.Abp.MultiTenancy.EntityFrameworkCore; namespace AbpDesk.EntityFrameworkCore { [ConnectionStringName(ConnectionStrings.DefaultConnectionStringName)] //Explicitly declares this module always uses the default connection string - public class AbpDeskDbContext : AbpDbContext + public class AbpDeskDbContext : AbpDbContext, IMultiTenancyDbContext { public DbSet Tickets { get; set; } + public DbSet Tenants { get; set; } + + public DbSet TenantConnectionStrings { get; set; } + public AbpDeskDbContext(DbContextOptions options) : base(options) { @@ -20,6 +26,8 @@ namespace AbpDesk.EntityFrameworkCore { base.OnModelCreating(modelBuilder); + this.ConfigureAbpMultiTenancy(modelBuilder); + //Use different classes to map each entity type? modelBuilder.Entity(b => { diff --git a/src/AbpDesk/AbpDesk.EntityFrameworkCore/AbpDesk/EntityFrameworkCore/AbpDeskEntityFrameworkCoreModule.cs b/src/AbpDesk/AbpDesk.EntityFrameworkCore/AbpDesk/EntityFrameworkCore/AbpDeskEntityFrameworkCoreModule.cs index 3538a2186e..022d8cfc3a 100644 --- a/src/AbpDesk/AbpDesk.EntityFrameworkCore/AbpDesk/EntityFrameworkCore/AbpDeskEntityFrameworkCoreModule.cs +++ b/src/AbpDesk/AbpDesk.EntityFrameworkCore/AbpDesk/EntityFrameworkCore/AbpDeskEntityFrameworkCoreModule.cs @@ -1,10 +1,15 @@ using Microsoft.Extensions.DependencyInjection; using Volo.Abp.EntityFrameworkCore; using Volo.Abp.Modularity; +using Volo.Abp.MultiTenancy.EntityFrameworkCore; namespace AbpDesk.EntityFrameworkCore { - [DependsOn(typeof(AbpDeskDomainModule), typeof(AbpEntityFrameworkCoreModule))] + [DependsOn( + typeof(AbpDeskDomainModule), + typeof(AbpEntityFrameworkCoreModule), + typeof(AbpMultiTenancyEntityFrameworkCoreModule) + )] public class AbpDeskEntityFrameworkCoreModule : AbpModule { public override void ConfigureServices(IServiceCollection services) diff --git a/src/AbpDesk/AbpDesk.EntityFrameworkCore/Migrations/20180105184326_MultiTenancyModuleAdded.Designer.cs b/src/AbpDesk/AbpDesk.EntityFrameworkCore/Migrations/20180105184326_MultiTenancyModuleAdded.Designer.cs new file mode 100644 index 0000000000..087141c5f3 --- /dev/null +++ b/src/AbpDesk/AbpDesk.EntityFrameworkCore/Migrations/20180105184326_MultiTenancyModuleAdded.Designer.cs @@ -0,0 +1,92 @@ +// +using AbpDesk.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage; +using Microsoft.EntityFrameworkCore.Storage.Internal; +using System; + +namespace AbpDesk.EntityFrameworkCore.Migrations +{ + [DbContext(typeof(AbpDeskDbContext))] + [Migration("20180105184326_MultiTenancyModuleAdded")] + partial class MultiTenancyModuleAdded + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "2.0.0-rtm-26452") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + modelBuilder.Entity("AbpDesk.Tickets.Ticket", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Body") + .HasMaxLength(65536); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken(); + + b.Property("Title") + .IsRequired() + .HasMaxLength(256); + + b.HasKey("Id"); + + b.ToTable("DskTickets"); + }); + + modelBuilder.Entity("Volo.Abp.MultiTenancy.Tenant", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Name") + .IsRequired() + .HasMaxLength(64); + + b.HasKey("Id"); + + b.HasIndex("Name"); + + b.ToTable("MtTenants"); + }); + + modelBuilder.Entity("Volo.Abp.MultiTenancy.TenantConnectionString", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256); + + b.Property("TenantId"); + + b.Property("Value") + .IsRequired() + .HasMaxLength(1024); + + b.HasKey("Id"); + + b.HasIndex("TenantId"); + + b.ToTable("MtTenantConnectionStrings"); + }); + + modelBuilder.Entity("Volo.Abp.MultiTenancy.TenantConnectionString", b => + { + b.HasOne("Volo.Abp.MultiTenancy.Tenant") + .WithMany("ConnectionStrings") + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/AbpDesk/AbpDesk.EntityFrameworkCore/Migrations/20180105184326_MultiTenancyModuleAdded.cs b/src/AbpDesk/AbpDesk.EntityFrameworkCore/Migrations/20180105184326_MultiTenancyModuleAdded.cs new file mode 100644 index 0000000000..3f9eae2ed0 --- /dev/null +++ b/src/AbpDesk/AbpDesk.EntityFrameworkCore/Migrations/20180105184326_MultiTenancyModuleAdded.cs @@ -0,0 +1,63 @@ +using Microsoft.EntityFrameworkCore.Migrations; +using System; +using System.Collections.Generic; + +namespace AbpDesk.EntityFrameworkCore.Migrations +{ + public partial class MultiTenancyModuleAdded : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "MtTenants", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + Name = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_MtTenants", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "MtTenantConnectionStrings", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + Name = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: false), + TenantId = table.Column(type: "uniqueidentifier", nullable: false), + Value = table.Column(type: "nvarchar(1024)", maxLength: 1024, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_MtTenantConnectionStrings", x => x.Id); + table.ForeignKey( + name: "FK_MtTenantConnectionStrings_MtTenants_TenantId", + column: x => x.TenantId, + principalTable: "MtTenants", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_MtTenantConnectionStrings_TenantId", + table: "MtTenantConnectionStrings", + column: "TenantId"); + + migrationBuilder.CreateIndex( + name: "IX_MtTenants_Name", + table: "MtTenants", + column: "Name"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "MtTenantConnectionStrings"); + + migrationBuilder.DropTable( + name: "MtTenants"); + } + } +} diff --git a/src/AbpDesk/AbpDesk.EntityFrameworkCore/Migrations/AbpDeskDbContextModelSnapshot.cs b/src/AbpDesk/AbpDesk.EntityFrameworkCore/Migrations/AbpDeskDbContextModelSnapshot.cs index b84a4c0fca..d355af3c6a 100644 --- a/src/AbpDesk/AbpDesk.EntityFrameworkCore/Migrations/AbpDeskDbContextModelSnapshot.cs +++ b/src/AbpDesk/AbpDesk.EntityFrameworkCore/Migrations/AbpDeskDbContextModelSnapshot.cs @@ -1,6 +1,12 @@ -using Microsoft.EntityFrameworkCore; +// +using AbpDesk.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage; +using Microsoft.EntityFrameworkCore.Storage.Internal; +using System; namespace AbpDesk.EntityFrameworkCore.Migrations { @@ -9,8 +15,9 @@ namespace AbpDesk.EntityFrameworkCore.Migrations { protected override void BuildModel(ModelBuilder modelBuilder) { +#pragma warning disable 612, 618 modelBuilder - .HasAnnotation("ProductVersion", "1.1.0-rtm-22752") + .HasAnnotation("ProductVersion", "2.0.0-rtm-26452") .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); modelBuilder.Entity("AbpDesk.Tickets.Ticket", b => @@ -32,6 +39,53 @@ namespace AbpDesk.EntityFrameworkCore.Migrations b.ToTable("DskTickets"); }); + + modelBuilder.Entity("Volo.Abp.MultiTenancy.Tenant", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Name") + .IsRequired() + .HasMaxLength(64); + + b.HasKey("Id"); + + b.HasIndex("Name"); + + b.ToTable("MtTenants"); + }); + + modelBuilder.Entity("Volo.Abp.MultiTenancy.TenantConnectionString", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256); + + b.Property("TenantId"); + + b.Property("Value") + .IsRequired() + .HasMaxLength(1024); + + b.HasKey("Id"); + + b.HasIndex("TenantId"); + + b.ToTable("MtTenantConnectionStrings"); + }); + + modelBuilder.Entity("Volo.Abp.MultiTenancy.TenantConnectionString", b => + { + b.HasOne("Volo.Abp.MultiTenancy.Tenant") + .WithMany("ConnectionStrings") + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade); + }); +#pragma warning restore 612, 618 } } } diff --git a/src/Volo.Abp.EntityFrameworkCore/Microsoft/Extensions/DependencyInjection/AbpEfCoreServiceCollectionExtensions.cs b/src/Volo.Abp.EntityFrameworkCore/Microsoft/Extensions/DependencyInjection/AbpEfCoreServiceCollectionExtensions.cs index 06a09c8075..f7ff4b87e8 100644 --- a/src/Volo.Abp.EntityFrameworkCore/Microsoft/Extensions/DependencyInjection/AbpEfCoreServiceCollectionExtensions.cs +++ b/src/Volo.Abp.EntityFrameworkCore/Microsoft/Extensions/DependencyInjection/AbpEfCoreServiceCollectionExtensions.cs @@ -7,7 +7,9 @@ namespace Microsoft.Extensions.DependencyInjection { public static class AbpEfCoreServiceCollectionExtensions { - public static IServiceCollection AddAbpDbContext(this IServiceCollection services, Action optionsBuilder = null) //Created overload instead of default parameter + public static IServiceCollection AddAbpDbContext( + this IServiceCollection services, + Action optionsBuilder = null) where TDbContext : AbpDbContext { services.AddMemoryCache(); diff --git a/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Domain/Repositories/EntityFrameworkCore/EfCoreRepository.cs b/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Domain/Repositories/EntityFrameworkCore/EfCoreRepository.cs index 8ed4a53b44..869d090176 100644 --- a/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Domain/Repositories/EntityFrameworkCore/EfCoreRepository.cs +++ b/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Domain/Repositories/EntityFrameworkCore/EfCoreRepository.cs @@ -12,7 +12,7 @@ using Volo.Abp.Threading; namespace Volo.Abp.Domain.Repositories.EntityFrameworkCore { public class EfCoreRepository : EfCoreRepository, IEfCoreRepository - where TDbContext : AbpDbContext + where TDbContext : IEfCoreDbContext where TEntity : class, IEntity { public EfCoreRepository(IDbContextProvider dbContextProvider) @@ -25,12 +25,12 @@ namespace Volo.Abp.Domain.Repositories.EntityFrameworkCore IEfCoreRepository, ISupportsExplicitLoading - where TDbContext : AbpDbContext + where TDbContext : IEfCoreDbContext where TEntity : class, IEntity { public virtual DbSet DbSet => DbContext.Set(); - DbContext IEfCoreRepository.DbContext => DbContext; + DbContext IEfCoreRepository.DbContext => DbContext.As(); protected virtual TDbContext DbContext => _dbContextProvider.GetDbContext(); diff --git a/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DependencyInjection/AbpDbContextRegistrationOptions.cs b/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DependencyInjection/AbpDbContextRegistrationOptions.cs index 172461a913..f2612f4b4b 100644 --- a/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DependencyInjection/AbpDbContextRegistrationOptions.cs +++ b/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DependencyInjection/AbpDbContextRegistrationOptions.cs @@ -1,4 +1,3 @@ -using Volo.Abp.Data; using Volo.Abp.DependencyInjection; namespace Volo.Abp.EntityFrameworkCore.DependencyInjection diff --git a/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/IDbContextProvider.cs b/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/IDbContextProvider.cs index d975596df1..c4655fddd0 100644 --- a/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/IDbContextProvider.cs +++ b/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/IDbContextProvider.cs @@ -1,7 +1,7 @@ namespace Volo.Abp.EntityFrameworkCore { public interface IDbContextProvider - where TDbContext : AbpDbContext + where TDbContext : IEfCoreDbContext { TDbContext GetDbContext(); } diff --git a/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/IEfCoreDbContext.cs b/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/IEfCoreDbContext.cs index 880d4112e3..7cba957724 100644 --- a/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/IEfCoreDbContext.cs +++ b/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/IEfCoreDbContext.cs @@ -1,14 +1,86 @@ -using Microsoft.EntityFrameworkCore; +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using JetBrains.Annotations; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.ChangeTracking; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Internal; namespace Volo.Abp.EntityFrameworkCore { - public interface IEfCoreDbContext + public interface IEfCoreDbContext : IDisposable, IInfrastructure, IDbContextDependencies, IDbSetCache, IDbContextPoolable { + EntityEntry Attach([NotNull] TEntity entity) where TEntity : class; + + EntityEntry Attach([NotNull] object entity); + int SaveChanges(); int SaveChanges(bool acceptAllChangesOnSuccess); + Task SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = default); + + Task SaveChangesAsync(CancellationToken cancellationToken = default); + DbSet Set() where T: class; + + DatabaseFacade Database { get; } + + ChangeTracker ChangeTracker { get; } + + EntityEntry Add([NotNull] object entity); + + EntityEntry Add([NotNull] TEntity entity) where TEntity : class; + + Task AddAsync([NotNull] object entity, CancellationToken cancellationToken = default); + + Task> AddAsync([NotNull] TEntity entity, CancellationToken cancellationToken = default) where TEntity : class; + + void AddRange([NotNull] IEnumerable entities); + + void AddRange([NotNull] params object[] entities); + + Task AddRangeAsync([NotNull] params object[] entities); + + Task AddRangeAsync([NotNull] IEnumerable entities, CancellationToken cancellationToken = default); + + void AttachRange([NotNull] IEnumerable entities); + + void AttachRange([NotNull] params object[] entities); + + EntityEntry Entry([NotNull] TEntity entity) where TEntity : class; + + EntityEntry Entry([NotNull] object entity); + + object Find([NotNull] Type entityType, [NotNull] params object[] keyValues); + + TEntity Find([NotNull] params object[] keyValues) where TEntity : class; + + Task FindAsync([NotNull] Type entityType, [NotNull] object[] keyValues, CancellationToken cancellationToken); + + Task FindAsync([NotNull] object[] keyValues, CancellationToken cancellationToken) where TEntity : class; + + Task FindAsync([NotNull] params object[] keyValues) where TEntity : class; + + Task FindAsync([NotNull] Type entityType, [NotNull] params object[] keyValues); + + EntityEntry Remove([NotNull] TEntity entity) where TEntity : class; + + EntityEntry Remove([NotNull] object entity); + + void RemoveRange([NotNull] IEnumerable entities); + + void RemoveRange([NotNull] params object[] entities); + + EntityEntry Update([NotNull] TEntity entity) where TEntity : class; + + EntityEntry Update([NotNull] object entity); + + void UpdateRange([NotNull] params object[] entities); + + void UpdateRange([NotNull] IEnumerable entities); } } diff --git a/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Uow/EntityFrameworkCore/EfCoreDatabaseApi.cs b/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Uow/EntityFrameworkCore/EfCoreDatabaseApi.cs index 3a45eb70fe..767bdf6e27 100644 --- a/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Uow/EntityFrameworkCore/EfCoreDatabaseApi.cs +++ b/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Uow/EntityFrameworkCore/EfCoreDatabaseApi.cs @@ -5,7 +5,7 @@ using Volo.Abp.EntityFrameworkCore; namespace Volo.Abp.Uow.EntityFrameworkCore { public class EfCoreDatabaseApi : IDatabaseApi, ISupportsSavingChanges - where TDbContext : AbpDbContext + where TDbContext : IEfCoreDbContext { public TDbContext DbContext { get; } diff --git a/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Uow/EntityFrameworkCore/EfCoreTransactionApi.cs b/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Uow/EntityFrameworkCore/EfCoreTransactionApi.cs index a715d8c150..33f9aca1a7 100644 --- a/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Uow/EntityFrameworkCore/EfCoreTransactionApi.cs +++ b/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Uow/EntityFrameworkCore/EfCoreTransactionApi.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; @@ -10,14 +11,14 @@ namespace Volo.Abp.Uow.EntityFrameworkCore public class EfCoreTransactionApi : ITransactionApi, ISupportsRollback { public IDbContextTransaction DbContextTransaction { get; } - public DbContext StarterDbContext { get; } - public List AttendedDbContexts { get; } + public IEfCoreDbContext StarterDbContext { get; } + public List AttendedDbContexts { get; } - public EfCoreTransactionApi(IDbContextTransaction dbContextTransaction, DbContext starterDbContext) + public EfCoreTransactionApi(IDbContextTransaction dbContextTransaction, IEfCoreDbContext starterDbContext) { DbContextTransaction = dbContextTransaction; StarterDbContext = starterDbContext; - AttendedDbContexts = new List(); + AttendedDbContexts = new List(); } public void Commit() @@ -26,7 +27,7 @@ namespace Volo.Abp.Uow.EntityFrameworkCore foreach (var dbContext in AttendedDbContexts) { - if (dbContext.HasRelationalTransactionManager()) + if (dbContext.As().HasRelationalTransactionManager()) { continue; //Relational databases use the shared transaction } diff --git a/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Uow/EntityFrameworkCore/UnitOfWorkDbContextProvider.cs b/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Uow/EntityFrameworkCore/UnitOfWorkDbContextProvider.cs index 596fc72917..a09d756cd2 100644 --- a/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Uow/EntityFrameworkCore/UnitOfWorkDbContextProvider.cs +++ b/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Uow/EntityFrameworkCore/UnitOfWorkDbContextProvider.cs @@ -11,7 +11,7 @@ namespace Volo.Abp.Uow.EntityFrameworkCore //TODO: Implement logic in DefaultDbContextResolver.Resolve in old ABP. public class UnitOfWorkDbContextProvider : IDbContextProvider - where TDbContext : AbpDbContext + where TDbContext : IEfCoreDbContext { private readonly IUnitOfWorkManager _unitOfWorkManager; private readonly IConnectionStringResolver _connectionStringResolver; @@ -100,7 +100,7 @@ namespace Volo.Abp.Uow.EntityFrameworkCore var dbContext = unitOfWork.ServiceProvider.GetRequiredService(); - if (dbContext.HasRelationalTransactionManager()) + if (dbContext.As().HasRelationalTransactionManager()) { dbContext.Database.UseTransaction(activeTransaction.DbContextTransaction.GetDbTransaction()); } diff --git a/src/Volo.Abp.MultiTenancy.EntityFrameworkCore/Volo/Abp/MultiTenancy/EntityFrameworkCore/AbpMultiTenancyEntityFrameworkCoreModule.cs b/src/Volo.Abp.MultiTenancy.EntityFrameworkCore/Volo/Abp/MultiTenancy/EntityFrameworkCore/AbpMultiTenancyEntityFrameworkCoreModule.cs index b8676711d8..b85fc5f2ac 100644 --- a/src/Volo.Abp.MultiTenancy.EntityFrameworkCore/Volo/Abp/MultiTenancy/EntityFrameworkCore/AbpMultiTenancyEntityFrameworkCoreModule.cs +++ b/src/Volo.Abp.MultiTenancy.EntityFrameworkCore/Volo/Abp/MultiTenancy/EntityFrameworkCore/AbpMultiTenancyEntityFrameworkCoreModule.cs @@ -10,6 +10,11 @@ namespace Volo.Abp.MultiTenancy.EntityFrameworkCore { public override void ConfigureServices(IServiceCollection services) { + services.AddAbpDbContext(options => + { + options.WithDefaultRepositories(); + }); + services.AddAssemblyOf(); } } From f768922ce5da2443a4619f4ffb875005bec0c96f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Sat, 6 Jan 2018 11:40:27 +0300 Subject: [PATCH 3/3] Implementing replacing a dbcontext. --- .../AbpDeskEntityFrameworkCoreModule.cs | 3 +- .../Blogging/AbpDeskMongoBlogModule.cs | 2 +- src/AbpDesk/Web_PlugIns/AbpDesk.MongoBlog.dll | Bin 15360 -> 15360 bytes .../CommonDbContextRegistrationOptions.cs | 55 ++++++++++++++++-- ...mmonDbContextRegistrationOptionsBuilder.cs | 40 ++++++++++++- .../Repositories/RepositoryRegistrarBase.cs | 17 +++--- .../AbpEfCoreServiceCollectionExtensions.cs | 16 ++++- .../AbpDbContextRegistrationOptions.cs | 5 ++ ...IAbpDbContextRegistrationOptionsBuilder.cs | 2 - .../AbpIdentityEntityFrameworkCoreModule.cs | 6 +- .../AbpIdentityServerModule.cs | 4 +- .../AbpMemoryDbServiceCollectionExtensions.cs | 15 ++++- ...moryDbContextRegistrationOptionsBuilder.cs | 1 - .../MemoryDbContextRegistrationOptions.cs | 7 ++- .../AbpMongoDbServiceCollectionExtensions.cs | 17 +++++- .../MongoDbContextRegistrationOptions.cs | 7 ++- ...bpMultiTenancyEntityFrameworkCoreModule.cs | 2 +- .../RepositoryRegistration_Tests.cs | 33 ++++++----- .../AbpEfCoreTestSecondContextModule.cs | 11 ++++ .../TestApp/ThirdDbContext/IThirdDbContext.cs | 9 +++ .../TestApp/ThirdDbContext/ThirdDbContext.cs | 16 +++++ .../ThirdDbContextDummyEntity.cs | 9 +++ .../AbpEntityFrameworkCoreTestModule.cs | 9 +-- .../DbContext_Replace_Tests.cs | 28 +++++++++ .../EntityFrameworkCore/TestAppDbContext.cs | 7 ++- .../Abp/MemoryDb/AbpMemoryDbTestModule.cs | 2 +- .../Volo/Abp/TestApp/TestAppModule.cs | 1 + 27 files changed, 259 insertions(+), 65 deletions(-) create mode 100644 test/Volo.Abp.EntityFrameworkCore.Tests.SecondContext/Volo/Abp/EntityFrameworkCore/TestApp/ThirdDbContext/IThirdDbContext.cs create mode 100644 test/Volo.Abp.EntityFrameworkCore.Tests.SecondContext/Volo/Abp/EntityFrameworkCore/TestApp/ThirdDbContext/ThirdDbContext.cs create mode 100644 test/Volo.Abp.EntityFrameworkCore.Tests.SecondContext/Volo/Abp/EntityFrameworkCore/TestApp/ThirdDbContext/ThirdDbContextDummyEntity.cs create mode 100644 test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/DbContext_Replace_Tests.cs diff --git a/src/AbpDesk/AbpDesk.EntityFrameworkCore/AbpDesk/EntityFrameworkCore/AbpDeskEntityFrameworkCoreModule.cs b/src/AbpDesk/AbpDesk.EntityFrameworkCore/AbpDesk/EntityFrameworkCore/AbpDeskEntityFrameworkCoreModule.cs index 022d8cfc3a..6c3c22d53e 100644 --- a/src/AbpDesk/AbpDesk.EntityFrameworkCore/AbpDesk/EntityFrameworkCore/AbpDeskEntityFrameworkCoreModule.cs +++ b/src/AbpDesk/AbpDesk.EntityFrameworkCore/AbpDesk/EntityFrameworkCore/AbpDeskEntityFrameworkCoreModule.cs @@ -16,7 +16,8 @@ namespace AbpDesk.EntityFrameworkCore { services.AddAbpDbContext(options => { - options.WithDefaultRepositories(); + options.AddDefaultRepositories(); + options.ReplaceDbContext(); }); services.AddAssemblyOf(); diff --git a/src/AbpDesk/AbpDesk.MongoBlog/AbpDesk/Blogging/AbpDeskMongoBlogModule.cs b/src/AbpDesk/AbpDesk.MongoBlog/AbpDesk/Blogging/AbpDeskMongoBlogModule.cs index 5154184d51..8e5df159d1 100644 --- a/src/AbpDesk/AbpDesk.MongoBlog/AbpDesk/Blogging/AbpDeskMongoBlogModule.cs +++ b/src/AbpDesk/AbpDesk.MongoBlog/AbpDesk/Blogging/AbpDeskMongoBlogModule.cs @@ -20,7 +20,7 @@ namespace AbpDesk.Blogging { services.AddMongoDbContext(options => { - options.WithDefaultRepositories(); + options.AddDefaultRepositories(); }); services.Configure(options => diff --git a/src/AbpDesk/Web_PlugIns/AbpDesk.MongoBlog.dll b/src/AbpDesk/Web_PlugIns/AbpDesk.MongoBlog.dll index 207e4f6c0792d8dc50f8671b4ed5af95a9fcc063..879b5f90bd5119f9448d4fee92d477a960437704 100644 GIT binary patch delta 741 zcmXYsT}V_x6vxlG_j>2f{g~Z$MRCr zu1*Z-G_ldpAz+Q53WLz2tKd_je9rx}u!Y)OFeFo(8z!}G%>`H3XUz>ea<}GzaoAKH z&_?_$3)bl|@#hSLi3(kU32=!X)^dSaOJqM}#g$+JG_g#<5|SyL-a;cfVB6Z@<$7{? zs%=A0fGA`24_95FXl4@}aivyb|j1NNDI{y;CT-_Tuf z$B6p-)iBYaS{cC-7-q|&PlSZjQdpoPSPF|`QwMlyvzX4#mPjttm`eo2Nx>*FcJ1(y z7VtD9DYc3jWC|o8LbpS@$likjdMsP!jYhV$&HPeBk6(T*6+#^EH_EVve=v^XG>CI9Lb_BfkCM4_ZwhVALFuErXahNYSoY=ds?l|5h@5wZhvQ@of4e(L7*5;u36fkw1J+=#MDb#tZD zjH+qyNejrkV1v^E&p0K>RAR&lSCjD~jS&}A=&O4NNa3!-@<+kCo5b*r3J!DgQ6t}Yxqt3og6Y~tH2@WRX zL8j4cjItu?Bl$)`&u1O$>4yf#=d8~MbzDeq{IEHaWfQmz@&hgF? zv0{akp!c|r{Taz!jwo9$)W*;4<(N53og3(bL+ n@N#aqF8*oG8)t1LyRAh-B~?d;uGKxTOv public abstract class CommonDbContextRegistrationOptions : ICommonDbContextRegistrationOptionsBuilder { - public bool SpecifiedDefaultRepositoryTypes => DefaultRepositoryImplementationType != null && DefaultRepositoryImplementationTypeWithDefaultPrimaryKey != null; - + public Type OriginalDbContextType { get; } + + public List ReplacedDbContextTypes { get; } + + public Type DefaultRepositoryDbContextType { get; protected set; } + public Type DefaultRepositoryImplementationType { get; private set; } public Type DefaultRepositoryImplementationTypeWithDefaultPrimaryKey { get; private set; } @@ -24,12 +28,34 @@ namespace Volo.Abp.DependencyInjection public Dictionary CustomRepositories { get; } - public CommonDbContextRegistrationOptions() + public bool SpecifiedDefaultRepositoryTypes => DefaultRepositoryImplementationType != null && DefaultRepositoryImplementationTypeWithDefaultPrimaryKey != null; + + protected CommonDbContextRegistrationOptions(Type originalDbContextType) { + OriginalDbContextType = originalDbContextType; + DefaultRepositoryDbContextType = originalDbContextType; CustomRepositories = new Dictionary(); + ReplacedDbContextTypes = new List(); + } + + public ICommonDbContextRegistrationOptionsBuilder ReplaceDbContext() + { + return ReplaceDbContext(typeof(TOtherDbContext)); + } + + public ICommonDbContextRegistrationOptionsBuilder ReplaceDbContext(Type otherDbContextType) + { + if (!otherDbContextType.IsAssignableFrom(OriginalDbContextType)) + { + throw new AbpException($"{OriginalDbContextType.AssemblyQualifiedName} should inherit/implement {otherDbContextType.AssemblyQualifiedName}!"); + } + + ReplacedDbContextTypes.Add(otherDbContextType); + + return this; } - public ICommonDbContextRegistrationOptionsBuilder WithDefaultRepositories(bool includeAllEntities = false) + public ICommonDbContextRegistrationOptionsBuilder AddDefaultRepositories(bool includeAllEntities = false) { RegisterDefaultRepositories = true; IncludeAllEntitiesForDefaultRepositories = includeAllEntities; @@ -37,14 +63,31 @@ namespace Volo.Abp.DependencyInjection return this; } - public ICommonDbContextRegistrationOptionsBuilder WithCustomRepository() + public ICommonDbContextRegistrationOptionsBuilder AddDefaultRepositories(bool includeAllEntities = false) + { + return AddDefaultRepositories(typeof(TDefaultRepositoryDbContext), includeAllEntities); + } + + public ICommonDbContextRegistrationOptionsBuilder AddDefaultRepositories(Type defaultRepositoryDbContextType, bool includeAllEntities = false) + { + if (!defaultRepositoryDbContextType.IsAssignableFrom(OriginalDbContextType)) + { + throw new AbpException($"{OriginalDbContextType.AssemblyQualifiedName} should inherit/implement {defaultRepositoryDbContextType.AssemblyQualifiedName}!"); + } + + DefaultRepositoryDbContextType = defaultRepositoryDbContextType; + + return this; + } + + public ICommonDbContextRegistrationOptionsBuilder AddCustomRepository() { WithCustomRepository(typeof(TEntity), typeof(TRepository)); return this; } - public ICommonDbContextRegistrationOptionsBuilder WithDefaultRepositoryClasses([NotNull] Type repositoryImplementationType, [NotNull] Type repositoryImplementationTypeWithDefaultPrimaryKey) + public ICommonDbContextRegistrationOptionsBuilder SetDefaultRepositoryClasses([NotNull] Type repositoryImplementationType, [NotNull] Type repositoryImplementationTypeWithDefaultPrimaryKey) { Check.NotNull(repositoryImplementationType, nameof(repositoryImplementationType)); Check.NotNull(repositoryImplementationTypeWithDefaultPrimaryKey, nameof(repositoryImplementationTypeWithDefaultPrimaryKey)); diff --git a/src/Volo.Abp.Ddd/Volo/Abp/DependencyInjection/ICommonDbContextRegistrationOptionsBuilder.cs b/src/Volo.Abp.Ddd/Volo/Abp/DependencyInjection/ICommonDbContextRegistrationOptionsBuilder.cs index 5528ca8b19..167fbcad47 100644 --- a/src/Volo.Abp.Ddd/Volo/Abp/DependencyInjection/ICommonDbContextRegistrationOptionsBuilder.cs +++ b/src/Volo.Abp.Ddd/Volo/Abp/DependencyInjection/ICommonDbContextRegistrationOptionsBuilder.cs @@ -11,7 +11,29 @@ namespace Volo.Abp.DependencyInjection /// Registers repositories only for aggregate root entities by default. /// set to true to include all entities. /// - ICommonDbContextRegistrationOptionsBuilder WithDefaultRepositories(bool includeAllEntities = false); + ICommonDbContextRegistrationOptionsBuilder AddDefaultRepositories(bool includeAllEntities = false); + + /// + /// Registers default repositories for this DbContext. + /// Default repositories will use given . + /// + /// DbContext type that will be used by default repositories + /// + /// Registers repositories only for aggregate root entities by default. + /// set to true to include all entities. + /// + ICommonDbContextRegistrationOptionsBuilder AddDefaultRepositories(bool includeAllEntities = false); + + /// + /// Registers default repositories for this DbContext. + /// Default repositories will use given . + /// + /// DbContext type that will be used by default repositories + /// + /// Registers repositories only for aggregate root entities by default. + /// set to true to include all entities. + /// + ICommonDbContextRegistrationOptionsBuilder AddDefaultRepositories(Type defaultRepositoryDbContextType, bool includeAllEntities = false); /// /// Registers custom repository for a specific entity. @@ -19,7 +41,7 @@ namespace Volo.Abp.DependencyInjection /// /// Entity type /// Repository type - ICommonDbContextRegistrationOptionsBuilder WithCustomRepository(); + ICommonDbContextRegistrationOptionsBuilder AddCustomRepository(); /// /// Uses given class(es) for default repositories. @@ -27,6 +49,18 @@ namespace Volo.Abp.DependencyInjection /// Repository implementation type /// Repository implementation type for default primary key type () /// - ICommonDbContextRegistrationOptionsBuilder WithDefaultRepositoryClasses(Type repositoryImplementationType, Type repositoryImplementationTypeWithDefaultPrimaryKey); + ICommonDbContextRegistrationOptionsBuilder SetDefaultRepositoryClasses(Type repositoryImplementationType, Type repositoryImplementationTypeWithDefaultPrimaryKey); + + /// + /// Replaces given DbContext type with this DbContext type. + /// + /// The DbContext type to be replaced + ICommonDbContextRegistrationOptionsBuilder ReplaceDbContext(); + + /// + /// Replaces given DbContext type with this DbContext type. + /// + /// The DbContext type to be replaced + ICommonDbContextRegistrationOptionsBuilder ReplaceDbContext(Type otherDbContextType); } } \ No newline at end of file diff --git a/src/Volo.Abp.Ddd/Volo/Abp/Domain/Repositories/RepositoryRegistrarBase.cs b/src/Volo.Abp.Ddd/Volo/Abp/Domain/Repositories/RepositoryRegistrarBase.cs index 6c2edc1f18..ea3e1963f8 100644 --- a/src/Volo.Abp.Ddd/Volo/Abp/Domain/Repositories/RepositoryRegistrarBase.cs +++ b/src/Volo.Abp.Ddd/Volo/Abp/Domain/Repositories/RepositoryRegistrarBase.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using Microsoft.Extensions.DependencyInjection; -using Volo.Abp.Data; using Volo.Abp.DependencyInjection; using Volo.Abp.Domain.Entities; using Volo.Abp.Reflection; @@ -18,7 +17,7 @@ namespace Volo.Abp.Domain.Repositories Options = options; } - public virtual void AddRepositories(IServiceCollection services, Type dbContextType) + public virtual void AddRepositories(IServiceCollection services) { foreach (var customRepository in Options.CustomRepositories) { @@ -27,24 +26,24 @@ namespace Volo.Abp.Domain.Repositories if (Options.RegisterDefaultRepositories) { - RegisterDefaultRepositories(services, dbContextType); + RegisterDefaultRepositories(services); } } - protected virtual void RegisterDefaultRepositories(IServiceCollection services, Type dbContextType) + protected virtual void RegisterDefaultRepositories(IServiceCollection services) { - foreach (var entityType in GetEntityTypes(dbContextType)) + foreach (var entityType in GetEntityTypes(Options.DefaultRepositoryDbContextType)) { if (!ShouldRegisterDefaultRepositoryFor(entityType)) { continue; } - RegisterDefaultRepository(services, dbContextType, entityType); + RegisterDefaultRepository(services, entityType); } } - protected void RegisterDefaultRepository(IServiceCollection services, Type dbContextType, Type entityType) + protected void RegisterDefaultRepository(IServiceCollection services, Type entityType) { var primaryKeyType = EntityHelper.GetPrimaryKeyType(entityType); var isDefaultPrimaryKey = primaryKeyType == typeof(Guid); @@ -59,8 +58,8 @@ namespace Volo.Abp.Domain.Repositories else { repositoryImplementationType = isDefaultPrimaryKey - ? GetRepositoryTypeForDefaultPk(dbContextType, entityType) - : GetRepositoryType(dbContextType, entityType, primaryKeyType); + ? GetRepositoryTypeForDefaultPk(Options.DefaultRepositoryDbContextType, entityType) + : GetRepositoryType(Options.DefaultRepositoryDbContextType, entityType, primaryKeyType); } services.AddDefaultRepository(entityType, repositoryImplementationType); diff --git a/src/Volo.Abp.EntityFrameworkCore/Microsoft/Extensions/DependencyInjection/AbpEfCoreServiceCollectionExtensions.cs b/src/Volo.Abp.EntityFrameworkCore/Microsoft/Extensions/DependencyInjection/AbpEfCoreServiceCollectionExtensions.cs index f7ff4b87e8..1236f17b2f 100644 --- a/src/Volo.Abp.EntityFrameworkCore/Microsoft/Extensions/DependencyInjection/AbpEfCoreServiceCollectionExtensions.cs +++ b/src/Volo.Abp.EntityFrameworkCore/Microsoft/Extensions/DependencyInjection/AbpEfCoreServiceCollectionExtensions.cs @@ -14,14 +14,24 @@ namespace Microsoft.Extensions.DependencyInjection { services.AddMemoryCache(); + var options = new AbpDbContextRegistrationOptions(typeof(TDbContext)); + optionsBuilder?.Invoke(options); + services.TryAddTransient(); services.TryAddTransient(DbContextOptionsFactory.Create); - var options = new AbpDbContextRegistrationOptions(); - optionsBuilder?.Invoke(options); + if (options.DefaultRepositoryDbContextType != typeof(TDbContext)) + { + services.TryAddTransient(options.DefaultRepositoryDbContextType, typeof(TDbContext)); + } + + foreach (var dbContextType in options.ReplacedDbContextTypes) + { + services.Replace(ServiceDescriptor.Transient(dbContextType, typeof(TDbContext))); + } new EfCoreRepositoryRegistrar(options) - .AddRepositories(services, typeof(TDbContext)); + .AddRepositories(services); return services; } diff --git a/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DependencyInjection/AbpDbContextRegistrationOptions.cs b/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DependencyInjection/AbpDbContextRegistrationOptions.cs index f2612f4b4b..484ceaa3ba 100644 --- a/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DependencyInjection/AbpDbContextRegistrationOptions.cs +++ b/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DependencyInjection/AbpDbContextRegistrationOptions.cs @@ -1,9 +1,14 @@ +using System; using Volo.Abp.DependencyInjection; namespace Volo.Abp.EntityFrameworkCore.DependencyInjection { public class AbpDbContextRegistrationOptions : CommonDbContextRegistrationOptions, IAbpDbContextRegistrationOptionsBuilder { + public AbpDbContextRegistrationOptions(Type originalDbContextType) + : base(originalDbContextType) + { + } } } \ No newline at end of file diff --git a/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DependencyInjection/IAbpDbContextRegistrationOptionsBuilder.cs b/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DependencyInjection/IAbpDbContextRegistrationOptionsBuilder.cs index db094128a6..0d812fb3cd 100644 --- a/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DependencyInjection/IAbpDbContextRegistrationOptionsBuilder.cs +++ b/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DependencyInjection/IAbpDbContextRegistrationOptionsBuilder.cs @@ -1,10 +1,8 @@ -using Volo.Abp.Data; using Volo.Abp.DependencyInjection; namespace Volo.Abp.EntityFrameworkCore.DependencyInjection { public interface IAbpDbContextRegistrationOptionsBuilder : ICommonDbContextRegistrationOptionsBuilder { - } } \ No newline at end of file diff --git a/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/AbpIdentityEntityFrameworkCoreModule.cs b/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/AbpIdentityEntityFrameworkCoreModule.cs index 8083fff741..fb3d42cb30 100644 --- a/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/AbpIdentityEntityFrameworkCoreModule.cs +++ b/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/AbpIdentityEntityFrameworkCoreModule.cs @@ -11,9 +11,9 @@ namespace Volo.Abp.Identity.EntityFrameworkCore { services.AddAbpDbContext(options => { - options.WithDefaultRepositories(); - options.WithCustomRepository(); - options.WithCustomRepository(); + options.AddDefaultRepositories(); + options.AddCustomRepository(); + options.AddCustomRepository(); }); services.AddAssemblyOf(); diff --git a/src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo/Abp/IdentityServer/EntityFrameworkCore/AbpIdentityServerModule.cs b/src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo/Abp/IdentityServer/EntityFrameworkCore/AbpIdentityServerModule.cs index b00b76a162..1d53416680 100644 --- a/src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo/Abp/IdentityServer/EntityFrameworkCore/AbpIdentityServerModule.cs +++ b/src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo/Abp/IdentityServer/EntityFrameworkCore/AbpIdentityServerModule.cs @@ -13,8 +13,8 @@ namespace Volo.Abp.IdentityServer.EntityFrameworkCore { services.AddAbpDbContext(options => { - options.WithDefaultRepositories(); - options.WithCustomRepository(); + options.AddDefaultRepositories(); + options.AddCustomRepository(); }); services.AddAssemblyOf(); diff --git a/src/Volo.Abp.MemoryDb/Microsoft/Extensions/DependencyInjection/AbpMemoryDbServiceCollectionExtensions.cs b/src/Volo.Abp.MemoryDb/Microsoft/Extensions/DependencyInjection/AbpMemoryDbServiceCollectionExtensions.cs index 2fbab6a9fd..cf6f9c7842 100644 --- a/src/Volo.Abp.MemoryDb/Microsoft/Extensions/DependencyInjection/AbpMemoryDbServiceCollectionExtensions.cs +++ b/src/Volo.Abp.MemoryDb/Microsoft/Extensions/DependencyInjection/AbpMemoryDbServiceCollectionExtensions.cs @@ -1,4 +1,5 @@ using System; +using Microsoft.Extensions.DependencyInjection.Extensions; using Volo.Abp.MemoryDb; using Volo.Abp.MemoryDb.DependencyInjection; @@ -9,13 +10,23 @@ namespace Microsoft.Extensions.DependencyInjection public static IServiceCollection AddMemoryDbContext(this IServiceCollection services, Action optionsBuilder = null) where TMemoryDbContext : MemoryDbContext { - var options = new MemoryDbContextRegistrationOptions(); + var options = new MemoryDbContextRegistrationOptions(typeof(TMemoryDbContext)); optionsBuilder?.Invoke(options); services.AddSingleton(); + if (options.DefaultRepositoryDbContextType != typeof(TMemoryDbContext)) + { + services.TryAddSingleton(options.DefaultRepositoryDbContextType, sp => sp.GetRequiredService()); + } + + foreach (var dbContextType in options.ReplacedDbContextTypes) + { + services.Replace(ServiceDescriptor.Singleton(dbContextType, sp => sp.GetRequiredService())); + } + new MemoryDbRepositoryRegistrar(options) - .AddRepositories(services, typeof(TMemoryDbContext)); + .AddRepositories(services); return services; } diff --git a/src/Volo.Abp.MemoryDb/Volo/Abp/MemoryDb/DependencyInjection/IMemoryDbContextRegistrationOptionsBuilder.cs b/src/Volo.Abp.MemoryDb/Volo/Abp/MemoryDb/DependencyInjection/IMemoryDbContextRegistrationOptionsBuilder.cs index 9fb3c21409..27081fe83c 100644 --- a/src/Volo.Abp.MemoryDb/Volo/Abp/MemoryDb/DependencyInjection/IMemoryDbContextRegistrationOptionsBuilder.cs +++ b/src/Volo.Abp.MemoryDb/Volo/Abp/MemoryDb/DependencyInjection/IMemoryDbContextRegistrationOptionsBuilder.cs @@ -1,4 +1,3 @@ -using Volo.Abp.Data; using Volo.Abp.DependencyInjection; namespace Volo.Abp.MemoryDb.DependencyInjection diff --git a/src/Volo.Abp.MemoryDb/Volo/Abp/MemoryDb/DependencyInjection/MemoryDbContextRegistrationOptions.cs b/src/Volo.Abp.MemoryDb/Volo/Abp/MemoryDb/DependencyInjection/MemoryDbContextRegistrationOptions.cs index a8150f988b..2d305ed0ee 100644 --- a/src/Volo.Abp.MemoryDb/Volo/Abp/MemoryDb/DependencyInjection/MemoryDbContextRegistrationOptions.cs +++ b/src/Volo.Abp.MemoryDb/Volo/Abp/MemoryDb/DependencyInjection/MemoryDbContextRegistrationOptions.cs @@ -1,10 +1,13 @@ -using Volo.Abp.Data; +using System; using Volo.Abp.DependencyInjection; namespace Volo.Abp.MemoryDb.DependencyInjection { public class MemoryDbContextRegistrationOptions : CommonDbContextRegistrationOptions, IMemoryDbContextRegistrationOptionsBuilder { - + public MemoryDbContextRegistrationOptions(Type originalDbContextType) + : base(originalDbContextType) + { + } } } \ No newline at end of file diff --git a/src/Volo.Abp.MongoDB/Microsoft/Extensions/DependencyInjection/AbpMongoDbServiceCollectionExtensions.cs b/src/Volo.Abp.MongoDB/Microsoft/Extensions/DependencyInjection/AbpMongoDbServiceCollectionExtensions.cs index 195ac135c4..c247e8374d 100644 --- a/src/Volo.Abp.MongoDB/Microsoft/Extensions/DependencyInjection/AbpMongoDbServiceCollectionExtensions.cs +++ b/src/Volo.Abp.MongoDB/Microsoft/Extensions/DependencyInjection/AbpMongoDbServiceCollectionExtensions.cs @@ -1,4 +1,5 @@ using System; +using Microsoft.Extensions.DependencyInjection.Extensions; using Volo.Abp.MongoDB; using Volo.Abp.MongoDB.DependencyInjection; @@ -9,13 +10,23 @@ namespace Microsoft.Extensions.DependencyInjection public static IServiceCollection AddMongoDbContext(this IServiceCollection services, Action optionsBuilder = null) //Created overload instead of default parameter where TMongoDbContext : AbpMongoDbContext { - var options = new MongoDbContextRegistrationOptions(); + var options = new MongoDbContextRegistrationOptions(typeof(TMongoDbContext)); optionsBuilder?.Invoke(options); - services.AddSingleton(); + services.TryAddSingleton(); + + if (options.DefaultRepositoryDbContextType != typeof(TMongoDbContext)) + { + services.TryAddSingleton(options.DefaultRepositoryDbContextType, sp => sp.GetRequiredService()); + } + + foreach (var dbContextType in options.ReplacedDbContextTypes) + { + services.Replace(ServiceDescriptor.Singleton(dbContextType, sp => sp.GetRequiredService())); + } new MongoDbRepositoryRegistrar(options) - .AddRepositories(services, typeof(TMongoDbContext)); + .AddRepositories(services); return services; } diff --git a/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/DependencyInjection/MongoDbContextRegistrationOptions.cs b/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/DependencyInjection/MongoDbContextRegistrationOptions.cs index 2c243cd871..6712f1e1ab 100644 --- a/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/DependencyInjection/MongoDbContextRegistrationOptions.cs +++ b/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/DependencyInjection/MongoDbContextRegistrationOptions.cs @@ -1,10 +1,13 @@ -using Volo.Abp.Data; +using System; using Volo.Abp.DependencyInjection; namespace Volo.Abp.MongoDB.DependencyInjection { public class MongoDbContextRegistrationOptions : CommonDbContextRegistrationOptions, IMongoDbContextRegistrationOptionsBuilder { - + public MongoDbContextRegistrationOptions(Type originalDbContextType) + : base(originalDbContextType) + { + } } } \ No newline at end of file diff --git a/src/Volo.Abp.MultiTenancy.EntityFrameworkCore/Volo/Abp/MultiTenancy/EntityFrameworkCore/AbpMultiTenancyEntityFrameworkCoreModule.cs b/src/Volo.Abp.MultiTenancy.EntityFrameworkCore/Volo/Abp/MultiTenancy/EntityFrameworkCore/AbpMultiTenancyEntityFrameworkCoreModule.cs index b85fc5f2ac..7a310864d8 100644 --- a/src/Volo.Abp.MultiTenancy.EntityFrameworkCore/Volo/Abp/MultiTenancy/EntityFrameworkCore/AbpMultiTenancyEntityFrameworkCoreModule.cs +++ b/src/Volo.Abp.MultiTenancy.EntityFrameworkCore/Volo/Abp/MultiTenancy/EntityFrameworkCore/AbpMultiTenancyEntityFrameworkCoreModule.cs @@ -12,7 +12,7 @@ namespace Volo.Abp.MultiTenancy.EntityFrameworkCore { services.AddAbpDbContext(options => { - options.WithDefaultRepositories(); + options.AddDefaultRepositories(); }); services.AddAssemblyOf(); diff --git a/test/Volo.Abp.Ddd.Tests/Volo/Abp/Domain/Repositories/RepositoryRegistration_Tests.cs b/test/Volo.Abp.Ddd.Tests/Volo/Abp/Domain/Repositories/RepositoryRegistration_Tests.cs index 88109c9670..fbbbc0c77c 100644 --- a/test/Volo.Abp.Ddd.Tests/Volo/Abp/Domain/Repositories/RepositoryRegistration_Tests.cs +++ b/test/Volo.Abp.Ddd.Tests/Volo/Abp/Domain/Repositories/RepositoryRegistration_Tests.cs @@ -17,12 +17,12 @@ namespace Volo.Abp.Domain.Repositories var services = new ServiceCollection(); - var options = new TestDbContextRegistrationOptions(); - options.WithDefaultRepositories(); + var options = new TestDbContextRegistrationOptions(typeof(MyFakeDbContext)); + options.AddDefaultRepositories(); //Act - new MyTestRepositoryRegistrar(options).AddRepositories(services, typeof(MyFakeDbContext)); + new MyTestRepositoryRegistrar(options).AddRepositories(services); //Assert @@ -38,12 +38,12 @@ namespace Volo.Abp.Domain.Repositories var services = new ServiceCollection(); - var options = new TestDbContextRegistrationOptions(); - options.WithDefaultRepositories(true); + var options = new TestDbContextRegistrationOptions(typeof(MyFakeDbContext)); + options.AddDefaultRepositories(true); //Act - new MyTestRepositoryRegistrar(options).AddRepositories(services, typeof(MyFakeDbContext)); + new MyTestRepositoryRegistrar(options).AddRepositories(services); //Assert @@ -59,14 +59,14 @@ namespace Volo.Abp.Domain.Repositories var services = new ServiceCollection(); - var options = new TestDbContextRegistrationOptions(); + var options = new TestDbContextRegistrationOptions(typeof(MyFakeDbContext)); options - .WithDefaultRepositories(true) - .WithCustomRepository(); + .AddDefaultRepositories(true) + .AddCustomRepository(); //Act - new MyTestRepositoryRegistrar(options).AddRepositories(services, typeof(MyFakeDbContext)); + new MyTestRepositoryRegistrar(options).AddRepositories(services); //Assert @@ -82,14 +82,14 @@ namespace Volo.Abp.Domain.Repositories var services = new ServiceCollection(); - var options = new TestDbContextRegistrationOptions(); + var options = new TestDbContextRegistrationOptions(typeof(MyFakeDbContext)); options - .WithDefaultRepositories(true) - .WithDefaultRepositoryClasses(typeof(MyTestCustomBaseRepository<,>), typeof(MyTestCustomBaseRepository<>)); + .AddDefaultRepositories(true) + .SetDefaultRepositoryClasses(typeof(MyTestCustomBaseRepository<,>), typeof(MyTestCustomBaseRepository<>)); //Act - new MyTestRepositoryRegistrar(options).AddRepositories(services, typeof(MyFakeDbContext)); + new MyTestRepositoryRegistrar(options).AddRepositories(services); //Assert @@ -196,7 +196,10 @@ namespace Volo.Abp.Domain.Repositories public class TestDbContextRegistrationOptions : CommonDbContextRegistrationOptions { - + public TestDbContextRegistrationOptions(Type originalDbContextType) + : base(originalDbContextType) + { + } } } } diff --git a/test/Volo.Abp.EntityFrameworkCore.Tests.SecondContext/Volo/Abp/EntityFrameworkCore/TestApp/SecondContext/AbpEfCoreTestSecondContextModule.cs b/test/Volo.Abp.EntityFrameworkCore.Tests.SecondContext/Volo/Abp/EntityFrameworkCore/TestApp/SecondContext/AbpEfCoreTestSecondContextModule.cs index 6e7f24139a..c72cc3cedf 100644 --- a/test/Volo.Abp.EntityFrameworkCore.Tests.SecondContext/Volo/Abp/EntityFrameworkCore/TestApp/SecondContext/AbpEfCoreTestSecondContextModule.cs +++ b/test/Volo.Abp.EntityFrameworkCore.Tests.SecondContext/Volo/Abp/EntityFrameworkCore/TestApp/SecondContext/AbpEfCoreTestSecondContextModule.cs @@ -1,4 +1,5 @@ using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.EntityFrameworkCore.TestApp.ThirdDbContext; using Volo.Abp.Modularity; namespace Volo.Abp.EntityFrameworkCore.TestApp.SecondContext @@ -8,6 +9,16 @@ namespace Volo.Abp.EntityFrameworkCore.TestApp.SecondContext { public override void ConfigureServices(IServiceCollection services) { + services.AddAbpDbContext(options => + { + options.AddDefaultRepositories(); + }); + + services.AddAbpDbContext(options => + { + options.AddDefaultRepositories(); + }); + services.AddAssemblyOf(); } diff --git a/test/Volo.Abp.EntityFrameworkCore.Tests.SecondContext/Volo/Abp/EntityFrameworkCore/TestApp/ThirdDbContext/IThirdDbContext.cs b/test/Volo.Abp.EntityFrameworkCore.Tests.SecondContext/Volo/Abp/EntityFrameworkCore/TestApp/ThirdDbContext/IThirdDbContext.cs new file mode 100644 index 0000000000..99e6d6410b --- /dev/null +++ b/test/Volo.Abp.EntityFrameworkCore.Tests.SecondContext/Volo/Abp/EntityFrameworkCore/TestApp/ThirdDbContext/IThirdDbContext.cs @@ -0,0 +1,9 @@ +using Microsoft.EntityFrameworkCore; + +namespace Volo.Abp.EntityFrameworkCore.TestApp.ThirdDbContext +{ + public interface IThirdDbContext : IEfCoreDbContext + { + DbSet DummyEntities { get; set; } + } +} \ No newline at end of file diff --git a/test/Volo.Abp.EntityFrameworkCore.Tests.SecondContext/Volo/Abp/EntityFrameworkCore/TestApp/ThirdDbContext/ThirdDbContext.cs b/test/Volo.Abp.EntityFrameworkCore.Tests.SecondContext/Volo/Abp/EntityFrameworkCore/TestApp/ThirdDbContext/ThirdDbContext.cs new file mode 100644 index 0000000000..bb001dc8e4 --- /dev/null +++ b/test/Volo.Abp.EntityFrameworkCore.Tests.SecondContext/Volo/Abp/EntityFrameworkCore/TestApp/ThirdDbContext/ThirdDbContext.cs @@ -0,0 +1,16 @@ +using Microsoft.EntityFrameworkCore; + +namespace Volo.Abp.EntityFrameworkCore.TestApp.ThirdDbContext +{ + /* This dbcontext is just for testing to replace dbcontext from the application using AbpDbContextRegistrationOptions.ReplaceDbContext + */ + public class ThirdDbContext : AbpDbContext, IThirdDbContext + { + public DbSet DummyEntities { get; set; } + + public ThirdDbContext(DbContextOptions options) + : base(options) + { + } + } +} diff --git a/test/Volo.Abp.EntityFrameworkCore.Tests.SecondContext/Volo/Abp/EntityFrameworkCore/TestApp/ThirdDbContext/ThirdDbContextDummyEntity.cs b/test/Volo.Abp.EntityFrameworkCore.Tests.SecondContext/Volo/Abp/EntityFrameworkCore/TestApp/ThirdDbContext/ThirdDbContextDummyEntity.cs new file mode 100644 index 0000000000..f88dfc2cb8 --- /dev/null +++ b/test/Volo.Abp.EntityFrameworkCore.Tests.SecondContext/Volo/Abp/EntityFrameworkCore/TestApp/ThirdDbContext/ThirdDbContextDummyEntity.cs @@ -0,0 +1,9 @@ +using Volo.Abp.Domain.Entities; + +namespace Volo.Abp.EntityFrameworkCore.TestApp.ThirdDbContext +{ + public class ThirdDbContextDummyEntity : AggregateRoot + { + public string Value { get; set; } + } +} \ No newline at end of file diff --git a/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/AbpEntityFrameworkCoreTestModule.cs b/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/AbpEntityFrameworkCoreTestModule.cs index 37ef8850a1..b6b77d26f8 100644 --- a/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/AbpEntityFrameworkCoreTestModule.cs +++ b/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/AbpEntityFrameworkCoreTestModule.cs @@ -3,6 +3,7 @@ using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using Volo.Abp.Autofac; using Volo.Abp.EntityFrameworkCore.TestApp.SecondContext; +using Volo.Abp.EntityFrameworkCore.TestApp.ThirdDbContext; using Volo.Abp.Modularity; using Volo.Abp.TestApp; using Volo.Abp.TestApp.EntityFrameworkCore; @@ -21,12 +22,8 @@ namespace Volo.Abp.EntityFrameworkCore services.AddAbpDbContext(options => { - options.WithDefaultRepositories(); - }); - - services.AddAbpDbContext(options => - { - options.WithDefaultRepositories(); + options.AddDefaultRepositories(); + options.ReplaceDbContext(); }); var inMemorySqlite = new SqliteConnection("Data Source=:memory:"); diff --git a/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/DbContext_Replace_Tests.cs b/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/DbContext_Replace_Tests.cs new file mode 100644 index 0000000000..a86797feed --- /dev/null +++ b/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/DbContext_Replace_Tests.cs @@ -0,0 +1,28 @@ +using Microsoft.Extensions.DependencyInjection; +using Shouldly; +using Volo.Abp.Domain.Repositories; +using Volo.Abp.EntityFrameworkCore.TestApp.ThirdDbContext; +using Volo.Abp.TestApp.EntityFrameworkCore; +using Xunit; + +namespace Volo.Abp.EntityFrameworkCore +{ + public class DbContext_Replace_Tests : EntityFrameworkCoreTestBase + { + private readonly IRepository _dummyRepository; + + public DbContext_Replace_Tests() + { + _dummyRepository = ServiceProvider.GetRequiredService>(); + } + + [Fact] + public void Should_Replace_DbContext() + { + (ServiceProvider.GetRequiredService() is TestAppDbContext).ShouldBeTrue(); + + (_dummyRepository.GetDbContext() is IThirdDbContext).ShouldBeTrue(); + (_dummyRepository.GetDbContext() is TestAppDbContext).ShouldBeTrue(); + } + } +} diff --git a/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/TestApp/EntityFrameworkCore/TestAppDbContext.cs b/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/TestApp/EntityFrameworkCore/TestAppDbContext.cs index 77373a84d5..f6088eb8a7 100644 --- a/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/TestApp/EntityFrameworkCore/TestAppDbContext.cs +++ b/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/TestApp/EntityFrameworkCore/TestAppDbContext.cs @@ -1,13 +1,16 @@ using Microsoft.EntityFrameworkCore; using Volo.Abp.EntityFrameworkCore; +using Volo.Abp.EntityFrameworkCore.TestApp.ThirdDbContext; using Volo.Abp.TestApp.Domain; namespace Volo.Abp.TestApp.EntityFrameworkCore { - public class TestAppDbContext : AbpDbContext + public class TestAppDbContext : AbpDbContext, IThirdDbContext { public DbSet People { get; set; } - + + public DbSet DummyEntities { get; set; } + public TestAppDbContext(DbContextOptions options) : base(options) { diff --git a/test/Volo.Abp.MemoryDb.Tests/Volo/Abp/MemoryDb/AbpMemoryDbTestModule.cs b/test/Volo.Abp.MemoryDb.Tests/Volo/Abp/MemoryDb/AbpMemoryDbTestModule.cs index 790e105b1d..86708d55ef 100644 --- a/test/Volo.Abp.MemoryDb.Tests/Volo/Abp/MemoryDb/AbpMemoryDbTestModule.cs +++ b/test/Volo.Abp.MemoryDb.Tests/Volo/Abp/MemoryDb/AbpMemoryDbTestModule.cs @@ -22,7 +22,7 @@ namespace Volo.Abp.MemoryDb services.AddMemoryDbContext(options => { - options.WithDefaultRepositories(); + options.AddDefaultRepositories(); }); services.AddAssemblyOf(); diff --git a/test/Volo.Abp.TestApp/Volo/Abp/TestApp/TestAppModule.cs b/test/Volo.Abp.TestApp/Volo/Abp/TestApp/TestAppModule.cs index 1714d543c4..145d361737 100644 --- a/test/Volo.Abp.TestApp/Volo/Abp/TestApp/TestAppModule.cs +++ b/test/Volo.Abp.TestApp/Volo/Abp/TestApp/TestAppModule.cs @@ -14,6 +14,7 @@ namespace Volo.Abp.TestApp public override void ConfigureServices(IServiceCollection services) { ConfigureAutoMapper(services); + services.AddAssemblyOf(); }