From a5524a700594b1642d0ace516f4f77d5fa5edb25 Mon Sep 17 00:00:00 2001 From: maliming Date: Wed, 7 Sep 2022 11:38:18 +0800 Subject: [PATCH 1/3] Add `SeedInSeparateUowAsync` method. --- .../Volo.Abp.Data/Volo/Abp/Data/DataSeeder.cs | 16 ++++++++++++---- .../Volo/Abp/Data/DataSeederExtensions.cs | 5 +++++ 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/framework/src/Volo.Abp.Data/Volo/Abp/Data/DataSeeder.cs b/framework/src/Volo.Abp.Data/Volo/Abp/Data/DataSeeder.cs index 0f930d1f70..8b01bcde77 100644 --- a/framework/src/Volo.Abp.Data/Volo/Abp/Data/DataSeeder.cs +++ b/framework/src/Volo.Abp.Data/Volo/Abp/Data/DataSeeder.cs @@ -25,13 +25,21 @@ public class DataSeeder : IDataSeeder, ITransientDependency { using (var scope = ServiceScopeFactory.CreateScope()) { + var manager = scope.ServiceProvider.GetRequiredService(); foreach (var contributorType in Options.Contributors) { - var contributor = (IDataSeedContributor)scope - .ServiceProvider - .GetRequiredService(contributorType); + using (var uow = manager.Begin( + requiresNew: context.Properties.ContainsKey(nameof(DataSeederExtensions.SeedInSeparateUowAsync)), + isTransactional: true)) + { + var contributor = (IDataSeedContributor)scope + .ServiceProvider + .GetRequiredService(contributorType); - await contributor.SeedAsync(context); + await contributor.SeedAsync(context); + + await uow.CompleteAsync(); + } } } } diff --git a/framework/src/Volo.Abp.Data/Volo/Abp/Data/DataSeederExtensions.cs b/framework/src/Volo.Abp.Data/Volo/Abp/Data/DataSeederExtensions.cs index 83fa974d85..8d8d7126c9 100644 --- a/framework/src/Volo.Abp.Data/Volo/Abp/Data/DataSeederExtensions.cs +++ b/framework/src/Volo.Abp.Data/Volo/Abp/Data/DataSeederExtensions.cs @@ -9,4 +9,9 @@ public static class DataSeederExtensions { return seeder.SeedAsync(new DataSeedContext(tenantId)); } + + public static Task SeedInSeparateUowAsync(this IDataSeeder seeder, Guid? tenantId = null) + { + return seeder.SeedAsync(new DataSeedContext(tenantId).WithProperty(nameof(DataSeederExtensions.SeedInSeparateUowAsync), true)); + } } From e5f4f40d25d2a64014bfe05b75e3d1fcc832ab96 Mon Sep 17 00:00:00 2001 From: maliming Date: Wed, 7 Sep 2022 13:09:25 +0800 Subject: [PATCH 2/3] Update DataSeeder.cs --- .../Volo.Abp.Data/Volo/Abp/Data/DataSeeder.cs | 27 +++++++++++-------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/framework/src/Volo.Abp.Data/Volo/Abp/Data/DataSeeder.cs b/framework/src/Volo.Abp.Data/Volo/Abp/Data/DataSeeder.cs index 8b01bcde77..2c3a467ce6 100644 --- a/framework/src/Volo.Abp.Data/Volo/Abp/Data/DataSeeder.cs +++ b/framework/src/Volo.Abp.Data/Volo/Abp/Data/DataSeeder.cs @@ -25,20 +25,25 @@ public class DataSeeder : IDataSeeder, ITransientDependency { using (var scope = ServiceScopeFactory.CreateScope()) { - var manager = scope.ServiceProvider.GetRequiredService(); - foreach (var contributorType in Options.Contributors) + if (context.Properties.ContainsKey(nameof(DataSeederExtensions.SeedInSeparateUowAsync))) { - using (var uow = manager.Begin( - requiresNew: context.Properties.ContainsKey(nameof(DataSeederExtensions.SeedInSeparateUowAsync)), - isTransactional: true)) + var manager = scope.ServiceProvider.GetRequiredService(); + foreach (var contributorType in Options.Contributors) { - var contributor = (IDataSeedContributor)scope - .ServiceProvider - .GetRequiredService(contributorType); - + using (var uow = manager.Begin(requiresNew: true, isTransactional: true)) + { + var contributor = (IDataSeedContributor)scope.ServiceProvider.GetRequiredService(contributorType); + await contributor.SeedAsync(context); + await uow.CompleteAsync(); + } + } + } + else + { + foreach (var contributorType in Options.Contributors) + { + var contributor = (IDataSeedContributor)scope.ServiceProvider.GetRequiredService(contributorType); await contributor.SeedAsync(context); - - await uow.CompleteAsync(); } } } From fbc32f5f891f42a881266e58ecfa5d6f39c169e4 Mon Sep 17 00:00:00 2001 From: maliming Date: Thu, 8 Sep 2022 14:28:05 +0800 Subject: [PATCH 3/3] Add `DataSeederExtensions_Tests`. --- .../Volo.Abp.Data/Volo/Abp/Data/DataSeeder.cs | 13 ++++-- .../Volo/Abp/Data/DataSeederExtensions.cs | 13 +++++- .../Abp/Data/DataSeederExtensions_Tests.cs | 43 +++++++++++++++++++ 3 files changed, 64 insertions(+), 5 deletions(-) create mode 100644 framework/test/Volo.Abp.Data.Tests/Volo/Abp/Data/DataSeederExtensions_Tests.cs diff --git a/framework/src/Volo.Abp.Data/Volo/Abp/Data/DataSeeder.cs b/framework/src/Volo.Abp.Data/Volo/Abp/Data/DataSeeder.cs index 2c3a467ce6..45729fcb86 100644 --- a/framework/src/Volo.Abp.Data/Volo/Abp/Data/DataSeeder.cs +++ b/framework/src/Volo.Abp.Data/Volo/Abp/Data/DataSeeder.cs @@ -1,4 +1,6 @@ -using System.Threading.Tasks; +using System; +using System.Linq; +using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using Volo.Abp.DependencyInjection; @@ -25,12 +27,17 @@ public class DataSeeder : IDataSeeder, ITransientDependency { using (var scope = ServiceScopeFactory.CreateScope()) { - if (context.Properties.ContainsKey(nameof(DataSeederExtensions.SeedInSeparateUowAsync))) + if (context.Properties.ContainsKey(DataSeederExtensions.SeedInSeparateUow)) { var manager = scope.ServiceProvider.GetRequiredService(); foreach (var contributorType in Options.Contributors) { - using (var uow = manager.Begin(requiresNew: true, isTransactional: true)) + var options = context.Properties.TryGetValue(DataSeederExtensions.SeedInSeparateUowOptions, out var uowOptions) + ? (AbpUnitOfWorkOptions) uowOptions + : new AbpUnitOfWorkOptions(); + var requiresNew = context.Properties.TryGetValue(DataSeederExtensions.SeedInSeparateUowRequiresNew, out var obj) && (bool) obj; + + using (var uow = manager.Begin(options, requiresNew)) { var contributor = (IDataSeedContributor)scope.ServiceProvider.GetRequiredService(contributorType); await contributor.SeedAsync(context); diff --git a/framework/src/Volo.Abp.Data/Volo/Abp/Data/DataSeederExtensions.cs b/framework/src/Volo.Abp.Data/Volo/Abp/Data/DataSeederExtensions.cs index 8d8d7126c9..bd17736b46 100644 --- a/framework/src/Volo.Abp.Data/Volo/Abp/Data/DataSeederExtensions.cs +++ b/framework/src/Volo.Abp.Data/Volo/Abp/Data/DataSeederExtensions.cs @@ -1,17 +1,26 @@ using System; using System.Threading.Tasks; +using Volo.Abp.Uow; namespace Volo.Abp.Data; public static class DataSeederExtensions { + public const string SeedInSeparateUow = "__SeedInSeparateUow"; + public const string SeedInSeparateUowOptions = "__SeedInSeparateUowOptions"; + public const string SeedInSeparateUowRequiresNew = "__SeedInSeparateUowRequiresNew"; + public static Task SeedAsync(this IDataSeeder seeder, Guid? tenantId = null) { return seeder.SeedAsync(new DataSeedContext(tenantId)); } - public static Task SeedInSeparateUowAsync(this IDataSeeder seeder, Guid? tenantId = null) + public static Task SeedInSeparateUowAsync(this IDataSeeder seeder, Guid? tenantId = null, AbpUnitOfWorkOptions options = null, bool requiresNew = false) { - return seeder.SeedAsync(new DataSeedContext(tenantId).WithProperty(nameof(DataSeederExtensions.SeedInSeparateUowAsync), true)); + var context = new DataSeedContext(tenantId); + context.WithProperty(SeedInSeparateUow, true); + context.WithProperty(SeedInSeparateUowOptions, options); + context.WithProperty(SeedInSeparateUowRequiresNew, requiresNew); + return seeder.SeedAsync(context); } } diff --git a/framework/test/Volo.Abp.Data.Tests/Volo/Abp/Data/DataSeederExtensions_Tests.cs b/framework/test/Volo.Abp.Data.Tests/Volo/Abp/Data/DataSeederExtensions_Tests.cs new file mode 100644 index 0000000000..25d20b58b5 --- /dev/null +++ b/framework/test/Volo.Abp.Data.Tests/Volo/Abp/Data/DataSeederExtensions_Tests.cs @@ -0,0 +1,43 @@ +using System; +using System.Data; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; +using NSubstitute; +using Volo.Abp.Modularity; +using Volo.Abp.Testing; +using Volo.Abp.Uow; +using Xunit; + +namespace Volo.Abp.Data; + +public class DataSeederExtensions_Tests : AbpIntegratedTest +{ + private IDataSeeder _dataSeeder; + + protected override void AfterAddApplication(IServiceCollection services) + { + _dataSeeder = Substitute.For(); + services.Replace(ServiceDescriptor.Singleton(_dataSeeder)); + base.AfterAddApplication(services); + } + + [Fact] + public void SeedInSeparateUowAsync() + { + var tenantId = Guid.NewGuid(); + _dataSeeder.SeedInSeparateUowAsync(tenantId, new AbpUnitOfWorkOptions(true, IsolationLevel.Serializable, 888), true); + + _dataSeeder.Received().SeedAsync(Arg.Is(x => x.TenantId == tenantId && + x.Properties[DataSeederExtensions.SeedInSeparateUow].To() == true && + x.Properties[DataSeederExtensions.SeedInSeparateUowOptions].As().IsTransactional == true && + x.Properties[DataSeederExtensions.SeedInSeparateUowOptions].As().IsolationLevel == IsolationLevel.Serializable && + x.Properties[DataSeederExtensions.SeedInSeparateUowOptions].As().Timeout == 888 && + x.Properties[DataSeederExtensions.SeedInSeparateUowRequiresNew].To() == true)); + } + + [DependsOn(typeof(AbpDataModule))] + public class TestModule : AbpModule + { + + } +}