Browse Source

添加localizationmangement并迁移Init

master
wwwk 3 years ago
parent
commit
8df6e6f819
  1. 3
      services/book-store/BookStore.csproj
  2. 31
      services/book-store/BookStoreModule.cs
  3. 2
      services/book-store/Data/BookStoreDbContext.cs
  4. 209
      services/book-store/Data/BookStoreDbMigrationService.cs
  5. 32
      services/book-store/Data/BookStoreEFCoreDbSchemaMigrator.cs
  6. 21
      services/book-store/DataSeeder/BookStoreDataSeederWorker.cs
  7. 8
      services/book-store/Localization/BookStore/ar.json
  8. 8
      services/book-store/Localization/BookStore/cs.json
  9. 8
      services/book-store/Localization/BookStore/de-DE.json
  10. 8
      services/book-store/Localization/BookStore/en-GB.json
  11. 8
      services/book-store/Localization/BookStore/es.json
  12. 8
      services/book-store/Localization/BookStore/fi.json
  13. 8
      services/book-store/Localization/BookStore/fr.json
  14. 8
      services/book-store/Localization/BookStore/hi.json
  15. 8
      services/book-store/Localization/BookStore/hu.json
  16. 8
      services/book-store/Localization/BookStore/is.json
  17. 8
      services/book-store/Localization/BookStore/it.json
  18. 8
      services/book-store/Localization/BookStore/nl.json
  19. 8
      services/book-store/Localization/BookStore/pl-PL.json
  20. 8
      services/book-store/Localization/BookStore/pt-BR.json
  21. 8
      services/book-store/Localization/BookStore/ro-RO.json
  22. 8
      services/book-store/Localization/BookStore/ru.json
  23. 8
      services/book-store/Localization/BookStore/sk.json
  24. 8
      services/book-store/Localization/BookStore/sl.json
  25. 8
      services/book-store/Localization/BookStore/tr.json
  26. 8
      services/book-store/Localization/BookStore/vi.json
  27. 8
      services/book-store/Localization/BookStore/zh-Hant.json
  28. 2409
      services/book-store/Migrations/20220501153835_Initlize.Designer.cs
  29. 1419
      services/book-store/Migrations/20220501153835_Initlize.cs
  30. 2407
      services/book-store/Migrations/BookStoreDbContextModelSnapshot.cs
  31. 20
      services/book-store/Program.cs

3
services/book-store/BookStore.csproj

@ -486,6 +486,9 @@
<ProjectReference Include="..\..\modules\common\Sanhe.Abp.Features.LimitValidation.Redis\Sanhe.Abp.Features.LimitValidation.Redis.csproj" />
<ProjectReference Include="..\..\modules\common\Sanhe.Abp.Hangfire.Dashboard\Sanhe.Abp.Hangfire.Dashboard.csproj" />
<ProjectReference Include="..\..\modules\common\Sanhe.Abp.Hangfire.Storage.PostgreSql\Sanhe.Abp.Hangfire.Storage.PostgreSql.csproj" />
<ProjectReference Include="..\..\modules\localization-management\Sanhe.Abp.LocalizationManagement.Application\Sanhe.Abp.LocalizationManagement.Application.csproj" />
<ProjectReference Include="..\..\modules\localization-management\Sanhe.Abp.LocalizationManagement.EntityFrameworkCore\Sanhe.Abp.LocalizationManagement.EntityFrameworkCore.csproj" />
<ProjectReference Include="..\..\modules\localization-management\Sanhe.Abp.LocalizationManagement.HttpApi\Sanhe.Abp.LocalizationManagement.HttpApi.csproj" />
<ProjectReference Include="..\..\modules\mvc\Sanhe.Abp.AspNetCore.Mvc.Wrapper\Sanhe.Abp.AspNetCore.Mvc.Wrapper.csproj" />
</ItemGroup>

31
services/book-store/BookStoreModule.cs

@ -1,4 +1,5 @@
using BookStore.Data;
using BookStore.DataSeeder;
using BookStore.Localization;
using Hangfire;
using Microsoft.AspNetCore.Builder;
@ -16,6 +17,9 @@ using Sanhe.Abp.ExceptionHandling.Emailing;
using Sanhe.Abp.Features.LimitValidation.Redis;
using Sanhe.Abp.Hangfire.Dashboard;
using Sanhe.Abp.Hangfire.Storage.PostgreSql;
using Sanhe.Abp.LocalizationManagement;
using Sanhe.Abp.LocalizationManagement.EntityFrameworkCore;
using Sanhe.Abp.Wrapper;
using StackExchange.Redis;
using System;
using System.Collections.Generic;
@ -115,7 +119,11 @@ namespace BookStore;
typeof(AbpEmailingExceptionHandlingModule),
typeof(AbpFeaturesValidationRedisModule),
typeof(AbpHangfireDashboardModule),
typeof(AbpHangfireStoragePostgreSqlModule)
typeof(AbpHangfireStoragePostgreSqlModule),
// LocalizationManagement
typeof(AbpLocalizationManagementApplicationModule),
typeof(AbpLocalizationManagementEntityFrameworkCoreModule),
typeof(AbpLocalizationManagementHttpApiModule)
)]
public class BookStoreModule : AbpModule
{
@ -139,11 +147,11 @@ public class BookStoreModule : AbpModule
context.Services.AddAlwaysAllowAuthorization();
// wrap
//Configure<AbpWrapperOptions>(options =>
//{
// options.IsEnabled = true;
// options.IgnoreNamespaces.Clear();
//});
Configure<AbpWrapperOptions>(options =>
{
options.IsEnabled = true;
options.IgnoreNamespaces.Clear();
});
// limit
Configure<AbpRedisRequiresLimitFeatureOptions>(options =>
{
@ -162,6 +170,7 @@ public class BookStoreModule : AbpModule
ConfigureCors(context, configuration);
//ConfigureDataProtection(context, configuration, hostingEnvironment);
ConfigureEfCore(context);
ConfigureSeedWorker(context.Services, hostingEnvironment.IsDevelopment());
}
private void ConfigureExceptionHandling()
@ -268,6 +277,8 @@ public class BookStoreModule : AbpModule
options.Languages.Add(new LanguageInfo("zh-Hans", "zh-Hans", "简体中文"));
options.Languages.Add(new LanguageInfo("en", "en", "English"));
// dynamic localization
options.Resources.AddDynamic();
});
Configure<AbpExceptionLocalizationOptions>(options =>
@ -356,6 +367,14 @@ public class BookStoreModule : AbpModule
});
}
private static void ConfigureSeedWorker(IServiceCollection services, bool isDevelopment = false)
{
if (isDevelopment)
{
services.AddHostedService<BookStoreDataSeederWorker>();
}
}
public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
var app = context.GetApplicationBuilder();

2
services/book-store/Data/BookStoreDbContext.cs

@ -1,4 +1,5 @@
using Microsoft.EntityFrameworkCore;
using Sanhe.Abp.LocalizationManagement.EntityFrameworkCore;
using Volo.Abp.AuditLogging.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.FeatureManagement.EntityFrameworkCore;
@ -30,6 +31,7 @@ public class BookStoreDbContext : AbpDbContext<BookStoreDbContext>
builder.ConfigureIdentityServer();
builder.ConfigureFeatureManagement();
builder.ConfigureTenantManagement();
builder.ConfigureLocalization();
/* Configure your own entities here */
}

209
services/book-store/Data/BookStoreDbMigrationService.cs

@ -1,209 +0,0 @@
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Identity;
using Volo.Abp.MultiTenancy;
using Volo.Abp.TenantManagement;
namespace BookStore.Data;
public class BookStoreDbMigrationService : ITransientDependency
{
public ILogger<BookStoreDbMigrationService> Logger { get; set; }
private readonly IDataSeeder _dataSeeder;
private readonly BookStoreEFCoreDbSchemaMigrator _dbSchemaMigrator;
private readonly ITenantRepository _tenantRepository;
private readonly ICurrentTenant _currentTenant;
public BookStoreDbMigrationService(
IDataSeeder dataSeeder,
BookStoreEFCoreDbSchemaMigrator dbSchemaMigrator,
ITenantRepository tenantRepository,
ICurrentTenant currentTenant)
{
_dataSeeder = dataSeeder;
_dbSchemaMigrator = dbSchemaMigrator;
_tenantRepository = tenantRepository;
_currentTenant = currentTenant;
Logger = NullLogger<BookStoreDbMigrationService>.Instance;
}
public async Task MigrateAsync()
{
var initialMigrationAdded = AddInitialMigrationIfNotExist();
if (initialMigrationAdded)
{
return;
}
Logger.LogInformation("Started database migrations...");
await MigrateDatabaseSchemaAsync();
await SeedDataAsync();
Logger.LogInformation($"Successfully completed host database migrations.");
var tenants = await _tenantRepository.GetListAsync(includeDetails: true);
var migratedDatabaseSchemas = new HashSet<string>();
foreach (var tenant in tenants)
{
using (_currentTenant.Change(tenant.Id))
{
if (tenant.ConnectionStrings.Any())
{
var tenantConnectionStrings = tenant.ConnectionStrings
.Select(x => x.Value)
.ToList();
if (!migratedDatabaseSchemas.IsSupersetOf(tenantConnectionStrings))
{
await MigrateDatabaseSchemaAsync(tenant);
migratedDatabaseSchemas.AddIfNotContains(tenantConnectionStrings);
}
}
await SeedDataAsync(tenant);
}
Logger.LogInformation($"Successfully completed {tenant.Name} tenant database migrations.");
}
Logger.LogInformation("Successfully completed all database migrations.");
Logger.LogInformation("You can safely end this process...");
}
private async Task MigrateDatabaseSchemaAsync(Tenant tenant = null)
{
Logger.LogInformation($"Migrating schema for {(tenant == null ? "host" : tenant.Name + " tenant")} database...");
await _dbSchemaMigrator.MigrateAsync();
}
private async Task SeedDataAsync(Tenant tenant = null)
{
Logger.LogInformation($"Executing {(tenant == null ? "host" : tenant.Name + " tenant")} database seed...");
await _dataSeeder.SeedAsync(new DataSeedContext(tenant?.Id)
.WithProperty(IdentityDataSeedContributor.AdminEmailPropertyName, IdentityDataSeedContributor.AdminEmailDefaultValue)
.WithProperty(IdentityDataSeedContributor.AdminPasswordPropertyName, IdentityDataSeedContributor.AdminPasswordDefaultValue)
);
}
private bool AddInitialMigrationIfNotExist()
{
try
{
if (!DbMigrationsProjectExists())
{
return false;
}
}
catch (Exception)
{
return false;
}
try
{
if (!MigrationsFolderExists())
{
AddInitialMigration();
return true;
}
else
{
return false;
}
}
catch (Exception e)
{
Logger.LogWarning("Couldn't determinate if any migrations exist : " + e.Message);
return false;
}
}
private bool DbMigrationsProjectExists()
{
return Directory.Exists(GetEntityFrameworkCoreProjectFolderPath());
}
private bool MigrationsFolderExists()
{
var dbMigrationsProjectFolder = GetEntityFrameworkCoreProjectFolderPath();
return Directory.Exists(Path.Combine(dbMigrationsProjectFolder, "Migrations"));
}
private void AddInitialMigration()
{
Logger.LogInformation("Creating initial migration...");
string argumentPrefix;
string fileName;
if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX) || RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
argumentPrefix = "-c";
fileName = "/bin/bash";
}
else
{
argumentPrefix = "/C";
fileName = "cmd.exe";
}
var procStartInfo = new ProcessStartInfo(fileName,
$"{argumentPrefix} \"abp create-migration-and-run-migrator \"{GetEntityFrameworkCoreProjectFolderPath()}\" --nolayers\""
);
try
{
Process.Start(procStartInfo);
}
catch (Exception)
{
throw new Exception("Couldn't run ABP CLI...");
}
}
private string GetEntityFrameworkCoreProjectFolderPath()
{
var slnDirectoryPath = GetSolutionDirectoryPath();
if (slnDirectoryPath == null)
{
throw new Exception("Solution folder not found!");
}
return Path.Combine(slnDirectoryPath, "BookStore");
}
private string GetSolutionDirectoryPath()
{
var currentDirectory = new DirectoryInfo(Directory.GetCurrentDirectory());
while (Directory.GetParent(currentDirectory.FullName) != null)
{
currentDirectory = Directory.GetParent(currentDirectory.FullName);
if (Directory.GetFiles(currentDirectory.FullName).FirstOrDefault(f => f.EndsWith(".sln")) != null)
{
return currentDirectory.FullName;
}
}
return null;
}
}

32
services/book-store/Data/BookStoreEFCoreDbSchemaMigrator.cs

@ -1,32 +0,0 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
namespace BookStore.Data;
public class BookStoreEFCoreDbSchemaMigrator : ITransientDependency
{
private readonly IServiceProvider _serviceProvider;
public BookStoreEFCoreDbSchemaMigrator(
IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public async Task MigrateAsync()
{
/* We intentionally resolving the BookStoreDbContext
* from IServiceProvider (instead of directly injecting it)
* to properly get the connection string of the current tenant in the
* current scope.
*/
await _serviceProvider
.GetRequiredService<BookStoreDbContext>()
.Database
.MigrateAsync();
}
}

21
services/book-store/DataSeeder/BookStoreDataSeederWorker.cs

@ -0,0 +1,21 @@
using Microsoft.Extensions.Hosting;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Data;
namespace BookStore.DataSeeder;
public class BookStoreDataSeederWorker : BackgroundService
{
protected IDataSeeder DataSeeder { get; }
public BookStoreDataSeederWorker(IDataSeeder dataSeeder)
{
DataSeeder = dataSeeder;
}
protected async override Task ExecuteAsync(CancellationToken stoppingToken)
{
await DataSeeder.SeedAsync();
}
}

8
services/book-store/Localization/BookStore/ar.json

@ -1,8 +0,0 @@
{
"culture": "ar",
"texts": {
"Welcome_Title": "مرحبا",
"Welcome_Text": "هذا هو قالب بدء تشغيل تطبيق ذو طبقة واحدة مبسط لإطار عمل ABP.",
"Menu:Home": "الرئيسية"
}
}

8
services/book-store/Localization/BookStore/cs.json

@ -1,8 +0,0 @@
{
"culture": "cs",
"texts": {
"Welcome_Title": "Vítejte",
"Welcome_Text": "Toto je minimalistická šablona pro spuštění aplikace s jednou vrstvou pro ABP Framework.",
"Menu:Home": "Úvod"
}
}

8
services/book-store/Localization/BookStore/de-DE.json

@ -1,8 +0,0 @@
{
"culture": "de-DE",
"texts": {
"Welcome_Title": "Willkommen",
"Welcome_Text": "Dies ist eine minimalistische, einschichtige Anwendungsstartvorlage für das ABP-Framework.",
"Menu:Home": "Home"
}
}

8
services/book-store/Localization/BookStore/en-GB.json

@ -1,8 +0,0 @@
{
"culture": "en-GB",
"texts": {
"Welcome_Title": "Welcome_Title",
"Welcome_Text": "This is a minimalist, single layer application startup template for the ABP Framework.",
"Menu:Home": "Home"
}
}

8
services/book-store/Localization/BookStore/es.json

@ -1,8 +0,0 @@
{
"culture": "es",
"texts": {
"Welcome_Title": "Bienvenido",
"Welcome_Text": "Esta es una plantilla de inicio de aplicación minimalista de una sola capa para ABP Framework.",
"Menu:Home": "Inicio"
}
}

8
services/book-store/Localization/BookStore/fi.json

@ -1,8 +0,0 @@
{
"culture": "fi",
"texts": {
"Welcome_Title": "Tervetuloa",
"Welcome_Text": "Tämä on minimalistinen yksikerroksinen sovelluksen käynnistysmalli ABP Frameworkille.",
"Menu:Home": "Koti"
}
}

8
services/book-store/Localization/BookStore/fr.json

@ -1,8 +0,0 @@
{
"culture": "fr",
"texts": {
"Welcome_Title": "Bienvenue",
"Welcome_Text": "Il s'agit d'un modèle de démarrage d'application minimaliste à une seule couche pour le cadre ABP.",
"Menu:Home": "Accueil"
}
}

8
services/book-store/Localization/BookStore/hi.json

@ -1,8 +0,0 @@
{
"culture": "hi",
"texts": {
"Welcome_Title": "सगत ह",
"Welcome_Text": "यह एबमवरक किए एक ननतम, सिगल लयर एपिशन सटअप टट ह।",
"Menu:Home": "घर"
}
}

8
services/book-store/Localization/BookStore/hu.json

@ -1,8 +0,0 @@
{
"culture": "hu",
"texts": {
"Welcome_Title": "Üdvözlöm",
"Welcome_Text": "Ez egy minimalista, egyrétegű alkalmazásindítási sablon az ABP-keretrendszerhez.",
"Menu:Home": "Kezdőlap"
}
}

8
services/book-store/Localization/BookStore/is.json

@ -1,8 +0,0 @@
{
"culture": "is",
"texts": {
"Welcome_Title": "Velkomin",
"Welcome_Text": "Þetta er lægstur, eins lags ræsingarsniðmát fyrir ABP Framework.",
"Menu:Home": "Heim"
}
}

8
services/book-store/Localization/BookStore/it.json

@ -1,8 +0,0 @@
{
"culture": "it",
"texts": {
"Welcome_Title": "Benvenuto",
"Welcome_Text": "Questo è un modello di avvio dell'applicazione minimalista a livello singolo per ABP Framework.",
"Menu:Home": "Home"
}
}

8
services/book-store/Localization/BookStore/nl.json

@ -1,8 +0,0 @@
{
"culture": "nl",
"texts": {
"Welcome_Title": "Welkom",
"Welcome_Text": "Dit is een minimalistische, enkellaagse applicatie-opstartsjabloon voor het ABP Framework.",
"Menu:Home": "Home"
}
}

8
services/book-store/Localization/BookStore/pl-PL.json

@ -1,8 +0,0 @@
{
"culture": "pl-PL",
"texts": {
"Welcome_Title": "Witaj",
"Welcome_Text": "Jest to minimalistyczny, jednowarstwowy szablon uruchamiania aplikacji dla ABP Framework.",
"Menu:Home": "Home"
}
}

8
services/book-store/Localization/BookStore/pt-BR.json

@ -1,8 +0,0 @@
{
"culture": "pt-BR",
"texts": {
"Welcome_Title": "Seja bem-vindo!",
"Welcome_Text": "Este é um modelo de inicialização de aplicativo de camada única minimalista para o ABP Framework.",
"Menu:Home": "Principal"
}
}

8
services/book-store/Localization/BookStore/ro-RO.json

@ -1,8 +0,0 @@
{
"culture": "ro-RO",
"texts": {
"Welcome_Title": "Bun venit",
"Welcome_Text": "Acesta este un șablon de pornire a aplicației minimaliste, cu un singur strat, pentru Cadrul ABP.",
"Menu:Home": "Acasă"
}
}

8
services/book-store/Localization/BookStore/ru.json

@ -1,8 +0,0 @@
{
"culture": "ru",
"texts": {
"Welcome_Title": "Bine ati venit",
"Welcome_Text": "Acesta este un șablon de pornire a aplicației minimaliste, cu un singur strat, pentru Cadrul ABP.",
"Menu:Home": "Главная"
}
}

8
services/book-store/Localization/BookStore/sk.json

@ -1,8 +0,0 @@
{
"culture": "sk",
"texts": {
"Welcome_Title": "Vitajte",
"Welcome_Text": "Toto je minimalistická šablóna na spustenie aplikácie s jednou vrstvou pre rámec ABP.",
"Menu:Home": "Domov"
}
}

8
services/book-store/Localization/BookStore/sl.json

@ -1,8 +0,0 @@
{
"culture": "sl",
"texts": {
"Welcome_Title": "Dobrodošli",
"Welcome_Text": "To je minimalistična enoslojna predloga za zagon aplikacije za ABP Framework.",
"Menu:Home": "Domov"
}
}

8
services/book-store/Localization/BookStore/tr.json

@ -1,8 +0,0 @@
{
"culture": "tr",
"texts": {
"Welcome_Title": "Hoşgeldiniz",
"Welcome_Text": "Bu proje tek katmanlı ABP uygulamaları yapmak için bir başlangıç şablonudur.",
"Menu:Home": "Ana sayfa"
}
}

8
services/book-store/Localization/BookStore/vi.json

@ -1,8 +0,0 @@
{
"culture": "vi",
"texts": {
"Welcome_Title": "Chào mừng bạn",
"Welcome_Text": "Đây là một mẫu khởi động ứng dụng lớp đơn, tối giản cho ABP Framework.",
"Menu:Home": "Trang chủ"
}
}

8
services/book-store/Localization/BookStore/zh-Hant.json

@ -1,8 +0,0 @@
{
"culture": "zh-Hant",
"texts": {
"Welcome_Title": "歡迎",
"Welcome_Text": "這是 ABP 框架的極簡單層應用程序啟動模板.",
"Menu:Home": "首頁"
}
}

2409
services/book-store/Migrations/20220501153835_Initlize.Designer.cs generated

File diff suppressed because it is too large Load Diff

1419
services/book-store/Migrations/20220501153835_Initlize.cs

File diff suppressed because it is too large Load Diff

2407
services/book-store/Migrations/BookStoreDbContextModelSnapshot.cs

File diff suppressed because it is too large Load Diff

20
services/book-store/Program.cs

@ -1,11 +1,9 @@
using BookStore.Data;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Serilog;
using Serilog.Events;
using System;
using System.Linq;
using System.Threading.Tasks;
namespace BookStore;
@ -30,13 +28,6 @@ public class Program
#else
.WriteTo.Async(c => c.File("Logs/logs.txt"));
#endif
if (IsMigrateDatabase(args))
{
loggerConfiguration.MinimumLevel.Override("Volo.Abp", LogEventLevel.Warning);
loggerConfiguration.MinimumLevel.Override("Microsoft", LogEventLevel.Warning);
loggerConfiguration.MinimumLevel.Override("IdentityServer4.Startup", LogEventLevel.Warning);
}
Log.Logger = loggerConfiguration.CreateLogger();
try
@ -49,12 +40,6 @@ public class Program
var app = builder.Build();
await app.InitializeApplicationAsync();
if (IsMigrateDatabase(args))
{
await app.Services.GetRequiredService<BookStoreDbMigrationService>().MigrateAsync();
return 0;
}
Log.Information("Starting BookStore.");
await app.RunAsync();
return 0;
@ -74,9 +59,4 @@ public class Program
Log.CloseAndFlush();
}
}
private static bool IsMigrateDatabase(string[] args)
{
return args.Any(x => x.Contains("--migrate-database", StringComparison.OrdinalIgnoreCase));
}
}

Loading…
Cancel
Save