Browse Source

Fixed #1123: Create a separated console application to migrate database and seed data.

pull/1156/head
Halil ibrahim Kalkan 7 years ago
parent
commit
9eff69dc96
  1. 33
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Mvc/MvcTemplateSwitchEntityFrameworkCoreToMongoDbStep.cs
  2. 9
      templates/mvc/MyCompanyName.MyProjectName.sln
  3. 32
      templates/mvc/src/MyCompanyName.MyProjectName.DbMigrator/MyCompanyName.MyProjectName.DbMigrator.csproj
  4. 15
      templates/mvc/src/MyCompanyName.MyProjectName.DbMigrator/MyProjectNameDbMigratorModule.cs
  5. 53
      templates/mvc/src/MyCompanyName.MyProjectName.DbMigrator/Program.cs
  6. 5
      templates/mvc/src/MyCompanyName.MyProjectName.DbMigrator/appsettings.json
  7. 23
      templates/mvc/src/MyCompanyName.MyProjectName.Domain/Data/DataSeedHelper.cs
  8. 9
      templates/mvc/src/MyCompanyName.MyProjectName.Domain/Data/IMyProjectNameDbSchemaMigrator.cs
  9. 39
      templates/mvc/src/MyCompanyName.MyProjectName.Domain/Data/MyProjectNameDbMigrationService.cs
  10. 16
      templates/mvc/src/MyCompanyName.MyProjectName.Domain/Data/NullMyProjectNameDbSchemaMigrator.cs
  11. 24
      templates/mvc/src/MyCompanyName.MyProjectName.EntityFrameworkCore.DbMigrations/EntityFrameworkCore/EntityFrameworkCoreMyProjectNameDbSchemaMigrator.cs
  12. 16
      templates/mvc/src/MyCompanyName.MyProjectName.EntityFrameworkCore.DbMigrations/EntityFrameworkCore/MyProjectNameEntityFrameworkCoreDbMigrationsModule.cs
  13. 2
      templates/mvc/src/MyCompanyName.MyProjectName.HttpApi.Host/MyProjectNameHttpApiHostModule.cs
  14. 8
      templates/mvc/src/MyCompanyName.MyProjectName.IdentityServer/MyProjectNameIdentityServerModule.cs
  15. 8
      templates/mvc/src/MyCompanyName.MyProjectName.Web/MyProjectNameWebModule.cs
  16. 2
      templates/mvc/test/MyCompanyName.MyProjectName.EntityFrameworkCore.Tests/EntityFrameworkCore/MyProjectNameEntityFrameworkCoreTestModule.cs
  17. 13
      templates/mvc/test/MyCompanyName.MyProjectName.TestBase/MyProjectNameTestBaseModule.cs

33
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Mvc/MvcTemplateSwitchEntityFrameworkCoreToMongoDbStep.cs

@ -21,7 +21,7 @@ namespace Volo.Abp.Cli.ProjectBuilding.Templates.Mvc
"/src/MyCompanyName.MyProjectName.Web/MyProjectNameWebModule.cs",
"MyCompanyName.MyProjectName.EntityFrameworkCore",
"MyCompanyName.MyProjectName.MongoDb",
"MyProjectNameEntityFrameworkCoreModule",
"MyProjectNameEntityFrameworkCoreDbMigrationsModule",
"MyProjectNameMongoDbModule"
);
@ -44,7 +44,7 @@ namespace Volo.Abp.Cli.ProjectBuilding.Templates.Mvc
"/src/MyCompanyName.MyProjectName.IdentityServer/MyProjectNameIdentityServerModule.cs",
"MyCompanyName.MyProjectName.EntityFrameworkCore",
"MyCompanyName.MyProjectName.MongoDb",
"MyProjectNameEntityFrameworkCoreModule",
"MyProjectNameEntityFrameworkCoreDbMigrationsModule",
"MyProjectNameMongoDbModule"
);
@ -67,7 +67,7 @@ namespace Volo.Abp.Cli.ProjectBuilding.Templates.Mvc
"/src/MyCompanyName.MyProjectName.HttpApi.Host/MyProjectNameHttpApiHostModule.cs",
"MyCompanyName.MyProjectName.EntityFrameworkCore",
"MyCompanyName.MyProjectName.MongoDb",
"MyProjectNameEntityFrameworkCoreModule",
"MyProjectNameEntityFrameworkCoreDbMigrationsModule",
"MyProjectNameMongoDbModule"
);
@ -76,8 +76,31 @@ namespace Volo.Abp.Cli.ProjectBuilding.Templates.Mvc
"/src/MyCompanyName.MyProjectName.HttpApi.Host/appsettings.json"
);
//MyCompanyName.MyProjectName.DbMigrator
ChangeProjectReference(
context,
"/src/MyCompanyName.MyProjectName.DbMigrator/MyCompanyName.MyProjectName.DbMigrator.csproj",
"EntityFrameworkCore.DbMigrations",
"MongoDB"
);
ChangeModuleDependency(
context,
"/src/MyCompanyName.MyProjectName.DbMigrator/MyProjectNameDbMigratorModule.cs",
"MyCompanyName.MyProjectName.EntityFrameworkCore",
"MyCompanyName.MyProjectName.MongoDb",
"MyProjectNameEntityFrameworkCoreDbMigrationsModule",
"MyProjectNameMongoDbModule"
);
ChangeConnectionStringToMongoDb(
context,
"/src/MyCompanyName.MyProjectName.DbMigrator/appsettings.json"
);
//MyCompanyName.MyProjectName.Domain.Tests
ChangeProjectReference(
context,
"/test/MyCompanyName.MyProjectName.Domain.Tests/MyCompanyName.MyProjectName.Domain.Tests.csproj",
@ -90,7 +113,7 @@ namespace Volo.Abp.Cli.ProjectBuilding.Templates.Mvc
"/test/MyCompanyName.MyProjectName.Domain.Tests/MyProjectNameDomainTestModule.cs",
"MyCompanyName.MyProjectName.EntityFrameworkCore",
"MyCompanyName.MyProjectName.MongoDb",
"MyProjectNameEntityFrameworkCoreTestModule",
"MyProjectNameEntityFrameworkCoreDbMigrationsModule",
"MyProjectNameMongoDbTestModule"
);
}

9
templates/mvc/MyCompanyName.MyProjectName.sln

@ -45,7 +45,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MyCompanyName.MyProjectName
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MyCompanyName.MyProjectName.MongoDB.Tests", "test\MyCompanyName.MyProjectName.MongoDB.Tests\MyCompanyName.MyProjectName.MongoDB.Tests.csproj", "{6015D17B-104B-4EC2-A9B7-D8A40C891458}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyCompanyName.MyProjectName.HttpApi.Client.ConsoleTestApp", "test\MyCompanyName.MyProjectName.HttpApi.Client.ConsoleTestApp\MyCompanyName.MyProjectName.HttpApi.Client.ConsoleTestApp.csproj", "{EF480016-9127-4916-8735-D2466BDBC582}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MyCompanyName.MyProjectName.HttpApi.Client.ConsoleTestApp", "test\MyCompanyName.MyProjectName.HttpApi.Client.ConsoleTestApp\MyCompanyName.MyProjectName.HttpApi.Client.ConsoleTestApp.csproj", "{EF480016-9127-4916-8735-D2466BDBC582}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyCompanyName.MyProjectName.DbMigrator", "src\MyCompanyName.MyProjectName.DbMigrator\MyCompanyName.MyProjectName.DbMigrator.csproj", "{AA94D832-1CCC-4715-95A9-A483F23A1A5D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -133,6 +135,10 @@ Global
{EF480016-9127-4916-8735-D2466BDBC582}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EF480016-9127-4916-8735-D2466BDBC582}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EF480016-9127-4916-8735-D2466BDBC582}.Release|Any CPU.Build.0 = Release|Any CPU
{AA94D832-1CCC-4715-95A9-A483F23A1A5D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AA94D832-1CCC-4715-95A9-A483F23A1A5D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AA94D832-1CCC-4715-95A9-A483F23A1A5D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AA94D832-1CCC-4715-95A9-A483F23A1A5D}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -158,6 +164,7 @@ Global
{E512F4D9-9375-480F-A2F6-A46509F9D824} = {04DBDB01-70F4-4E06-B468-8F87850B22BE}
{6015D17B-104B-4EC2-A9B7-D8A40C891458} = {04DBDB01-70F4-4E06-B468-8F87850B22BE}
{EF480016-9127-4916-8735-D2466BDBC582} = {04DBDB01-70F4-4E06-B468-8F87850B22BE}
{AA94D832-1CCC-4715-95A9-A483F23A1A5D} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {28315BFD-90E7-4E14-A2EA-F3D23AF4126F}

32
templates/mvc/src/MyCompanyName.MyProjectName.DbMigrator/MyCompanyName.MyProjectName.DbMigrator.csproj

@ -0,0 +1,32 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\common.props" />
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.2</TargetFramework>
</PropertyGroup>
<ItemGroup>
<None Remove="appsettings.json" />
</ItemGroup>
<ItemGroup>
<Content Include="appsettings.json">
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Serilog.Extensions.Logging" Version="2.0.4" />
<PackageReference Include="Serilog.Sinks.File" Version="4.0.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\framework\src\Volo.Abp.Autofac\Volo.Abp.Autofac.csproj" />
<ProjectReference Include="..\MyCompanyName.MyProjectName.EntityFrameworkCore.DbMigrations\MyCompanyName.MyProjectName.EntityFrameworkCore.DbMigrations.csproj" />
</ItemGroup>
</Project>

15
templates/mvc/src/MyCompanyName.MyProjectName.DbMigrator/MyProjectNameDbMigratorModule.cs

@ -0,0 +1,15 @@
using MyCompanyName.MyProjectName.EntityFrameworkCore;
using Volo.Abp.Autofac;
using Volo.Abp.Modularity;
namespace MyCompanyName.MyProjectName.DbMigrator
{
[DependsOn(
typeof(AbpAutofacModule),
typeof(MyProjectNameEntityFrameworkCoreDbMigrationsModule)
)]
public class MyProjectNameDbMigratorModule : AbpModule
{
}
}

53
templates/mvc/src/MyCompanyName.MyProjectName.DbMigrator/Program.cs

@ -0,0 +1,53 @@
using System.IO;
using Microsoft.Extensions.DependencyInjection;
using MyCompanyName.MyProjectName.Data;
using Serilog;
using Serilog.Events;
using Volo.Abp;
using Volo.Abp.Threading;
namespace MyCompanyName.MyProjectName.DbMigrator
{
class Program
{
static void Main(string[] args)
{
ConfigureLogging();
using (var application = AbpApplicationFactory.Create<MyProjectNameDbMigratorModule>(options =>
{
options.UseAutofac();
options.Services.AddLogging(c => c.AddSerilog());
}))
{
application.Initialize();
AsyncHelper.RunSync(
() => application
.ServiceProvider
.GetRequiredService<MyProjectNameDbMigrationService>()
.MigrateAsync()
);
application.Shutdown();
}
}
private static void ConfigureLogging()
{
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Information()
.MinimumLevel.Override("Microsoft", LogEventLevel.Warning)
.MinimumLevel.Override("Volo.Abp", LogEventLevel.Warning)
#if DEBUG
.MinimumLevel.Override("MyCompanyName.MyProjectName", LogEventLevel.Debug)
#else
.MinimumLevel.Override("MyCompanyName.MyProjectName", LogEventLevel.Information)
#endif
.Enrich.FromLogContext()
.WriteTo.File(Path.Combine(Directory.GetCurrentDirectory(), "Logs/logs.txt"))
.WriteTo.Console()
.CreateLogger();
}
}
}

5
templates/mvc/src/MyCompanyName.MyProjectName.DbMigrator/appsettings.json

@ -0,0 +1,5 @@
{
"ConnectionStrings": {
"Default": "Server=localhost;Database=MyProjectName;Trusted_Connection=True;MultipleActiveResultSets=true"
}
}

23
templates/mvc/src/MyCompanyName.MyProjectName.Domain/Data/DataSeedHelper.cs

@ -1,23 +0,0 @@
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp;
using Volo.Abp.Data;
using Volo.Abp.Threading;
namespace MyCompanyName.MyProjectName.Data
{
public static class DataSeedHelper
{
public static void Seed(ApplicationInitializationContext context)
{
AsyncHelper.RunSync(async () =>
{
using (var scope = context.ServiceProvider.CreateScope())
{
await scope.ServiceProvider
.GetRequiredService<IDataSeeder>()
.SeedAsync();
}
});
}
}
}

9
templates/mvc/src/MyCompanyName.MyProjectName.Domain/Data/IMyProjectNameDbSchemaMigrator.cs

@ -0,0 +1,9 @@
using System.Threading.Tasks;
namespace MyCompanyName.MyProjectName.Data
{
public interface IMyProjectNameDbSchemaMigrator
{
Task MigrateAsync();
}
}

39
templates/mvc/src/MyCompanyName.MyProjectName.Domain/Data/MyProjectNameDbMigrationService.cs

@ -0,0 +1,39 @@
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
namespace MyCompanyName.MyProjectName.Data
{
public class MyProjectNameDbMigrationService : ITransientDependency
{
public ILogger<MyProjectNameDbMigrationService> Logger { get; set; }
private readonly IDataSeeder _dataSeeder;
private readonly IMyProjectNameDbSchemaMigrator _dbSchemaMigrator;
public MyProjectNameDbMigrationService(
IDataSeeder dataSeeder,
IMyProjectNameDbSchemaMigrator dbSchemaMigrator)
{
_dataSeeder = dataSeeder;
_dbSchemaMigrator = dbSchemaMigrator;
Logger = NullLogger<MyProjectNameDbMigrationService>.Instance;
}
public async Task MigrateAsync()
{
Logger.LogInformation("Started database migrations...");
Logger.LogInformation("Migrating database schema...");
await _dbSchemaMigrator.MigrateAsync();
Logger.LogInformation("Executing database seed...");
await _dataSeeder.SeedAsync();
Logger.LogInformation("Successfully completed database migrations.");
}
}
}

16
templates/mvc/src/MyCompanyName.MyProjectName.Domain/Data/NullMyProjectNameDbSchemaMigrator.cs

@ -0,0 +1,16 @@
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
namespace MyCompanyName.MyProjectName.Data
{
/* This is used if database provider does't define
* IMyProjectNameDbSchemaMigrator implementation.
*/
public class NullMyProjectNameDbSchemaMigrator : IMyProjectNameDbSchemaMigrator, ITransientDependency
{
public Task MigrateAsync()
{
return Task.CompletedTask;
}
}
}

24
templates/mvc/src/MyCompanyName.MyProjectName.EntityFrameworkCore.DbMigrations/EntityFrameworkCore/EntityFrameworkCoreMyProjectNameDbSchemaMigrator.cs

@ -0,0 +1,24 @@
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using MyCompanyName.MyProjectName.Data;
using Volo.Abp.DependencyInjection;
namespace MyCompanyName.MyProjectName.EntityFrameworkCore
{
[Dependency(ReplaceServices = true)]
public class EntityFrameworkCoreMyProjectNameDbSchemaMigrator
: IMyProjectNameDbSchemaMigrator, ITransientDependency
{
private readonly MyProjectNameMigrationsDbContext _dbContext;
public EntityFrameworkCoreMyProjectNameDbSchemaMigrator(MyProjectNameMigrationsDbContext dbContext)
{
_dbContext = dbContext;
}
public async Task MigrateAsync()
{
await _dbContext.Database.MigrateAsync();
}
}
}

16
templates/mvc/src/MyCompanyName.MyProjectName.EntityFrameworkCore.DbMigrations/EntityFrameworkCore/MyProjectNameEntityFrameworkCoreDbMigrationsModule.cs

@ -0,0 +1,16 @@
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Modularity;
namespace MyCompanyName.MyProjectName.EntityFrameworkCore
{
[DependsOn(
typeof(MyProjectNameEntityFrameworkCoreModule)
)]
public class MyProjectNameEntityFrameworkCoreDbMigrationsModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddAbpDbContext<MyProjectNameMigrationsDbContext>();
}
}
}

2
templates/mvc/src/MyCompanyName.MyProjectName.HttpApi.Host/MyProjectNameHttpApiHostModule.cs

@ -23,7 +23,7 @@ namespace MyCompanyName.MyProjectName
typeof(AbpAutofacModule),
typeof(AbpAspNetCoreMultiTenancyModule),
typeof(MyProjectNameApplicationModule),
typeof(MyProjectNameEntityFrameworkCoreModule)
typeof(MyProjectNameEntityFrameworkCoreDbMigrationsModule)
)]
public class MyProjectNameHttpApiHostModule : AbpModule
{

8
templates/mvc/src/MyCompanyName.MyProjectName.IdentityServer/MyProjectNameIdentityServerModule.cs

@ -4,7 +4,6 @@ using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using MyCompanyName.MyProjectName.Data;
using MyCompanyName.MyProjectName.EntityFrameworkCore;
using MyCompanyName.MyProjectName.Localization;
using MyCompanyName.MyProjectName.MultiTenancy;
@ -30,7 +29,7 @@ namespace MyCompanyName.MyProjectName
typeof(AbpAutofacModule),
typeof(AbpAccountWebIdentityServerModule),
typeof(AbpAspNetCoreMvcUiBasicThemeModule),
typeof(MyProjectNameEntityFrameworkCoreModule)
typeof(MyProjectNameEntityFrameworkCoreDbMigrationsModule)
)]
public class MyProjectNameIdentityServerModule : AbpModule
{
@ -116,11 +115,6 @@ namespace MyCompanyName.MyProjectName
app.UseAbpRequestLocalization();
app.UseAuditing();
app.UseMvcWithDefaultRouteAndArea();
/* Seeding in the application startup can be a problem in a clustered environment.
* See https://github.com/abpframework/abp/issues/1123
*/
DataSeedHelper.Seed(context);
}
}
}

8
templates/mvc/src/MyCompanyName.MyProjectName.Web/MyProjectNameWebModule.cs

@ -7,7 +7,6 @@ using MyCompanyName.MyProjectName.Menus;
using Swashbuckle.AspNetCore.Swagger;
using System.IO;
using Microsoft.Extensions.Configuration;
using MyCompanyName.MyProjectName.Data;
using MyCompanyName.MyProjectName.Localization;
using MyCompanyName.MyProjectName.MultiTenancy;
using Volo.Abp;
@ -35,7 +34,7 @@ namespace MyCompanyName.MyProjectName
[DependsOn(
typeof(MyProjectNameHttpApiModule),
typeof(MyProjectNameApplicationModule),
typeof(MyProjectNameEntityFrameworkCoreModule),
typeof(MyProjectNameEntityFrameworkCoreDbMigrationsModule),
typeof(AbpAutofacModule),
typeof(AbpIdentityWebModule),
typeof(AbpAccountWebIdentityServerModule),
@ -204,11 +203,6 @@ namespace MyCompanyName.MyProjectName
});
app.UseAuditing();
app.UseMvcWithDefaultRouteAndArea();
/* Seeding in the application startup can be a problem in a clustered environment.
* See https://github.com/abpframework/abp/issues/1123
*/
DataSeedHelper.Seed(context);
}
}
}

2
templates/mvc/test/MyCompanyName.MyProjectName.EntityFrameworkCore.Tests/EntityFrameworkCore/MyProjectNameEntityFrameworkCoreTestModule.cs

@ -10,7 +10,7 @@ using Volo.Abp.Modularity;
namespace MyCompanyName.MyProjectName.EntityFrameworkCore
{
[DependsOn(
typeof(MyProjectNameEntityFrameworkCoreModule),
typeof(MyProjectNameEntityFrameworkCoreDbMigrationsModule),
typeof(MyProjectNameTestBaseModule)
)]
public class MyProjectNameEntityFrameworkCoreTestModule : AbpModule

13
templates/mvc/test/MyCompanyName.MyProjectName.TestBase/MyProjectNameTestBaseModule.cs

@ -1,10 +1,11 @@
using Microsoft.Extensions.DependencyInjection;
using MyCompanyName.MyProjectName.Data;
using Volo.Abp;
using Volo.Abp.Authorization;
using Volo.Abp.Autofac;
using Volo.Abp.BackgroundJobs;
using Volo.Abp.Data;
using Volo.Abp.Modularity;
using Volo.Abp.Threading;
namespace MyCompanyName.MyProjectName
{
@ -33,7 +34,15 @@ namespace MyCompanyName.MyProjectName
private static void SeedTestData(ApplicationInitializationContext context)
{
DataSeedHelper.Seed(context);
AsyncHelper.RunSync(async () =>
{
using (var scope = context.ServiceProvider.CreateScope())
{
await scope.ServiceProvider
.GetRequiredService<IDataSeeder>()
.SeedAsync();
}
});
}
}
}

Loading…
Cancel
Save