Browse Source

initialize multi-lingual-entities

pull/5774/head
liangshiwei 6 years ago
parent
commit
8623d8202b
  1. 7
      framework/Volo.Abp.sln
  2. 99
      framework/src/Volo.Abp.AutoMapper/AutoMapper/AbpAutoMapperMultiLingualDtoExtensions.cs
  3. 1
      framework/src/Volo.Abp.AutoMapper/Volo.Abp.AutoMapper.csproj
  4. 1
      framework/src/Volo.Abp.Ddd.Domain/Volo.Abp.Ddd.Domain.csproj
  5. 21
      framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/Modeling/AbpEntityTypeBuilderExtensions.cs
  6. 3
      framework/src/Volo.Abp.MultiLingualEntities/FodyWeavers.xml
  7. 30
      framework/src/Volo.Abp.MultiLingualEntities/FodyWeavers.xsd
  8. 11
      framework/src/Volo.Abp.MultiLingualEntities/Volo.Abp.MultiLingualEntities.csproj
  9. 19
      framework/src/Volo.Abp.MultiLingualEntities/Volo/Abp/MultiLingualEntities/IEntityTranslation.cs
  10. 10
      framework/src/Volo.Abp.MultiLingualEntities/Volo/Abp/MultiLingualEntities/IMultiLingualEntity.cs

7
framework/Volo.Abp.sln

@ -331,6 +331,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.GlobalFeatures", "
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.GlobalFeatures.Tests", "test\Volo.Abp.GlobalFeatures.Tests\Volo.Abp.GlobalFeatures.Tests.csproj", "{231F1581-AA21-44C3-BF27-51EB3AD5355C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.MultiLingualEntities", "src\Volo.Abp.MultiLingualEntities\Volo.Abp.MultiLingualEntities.csproj", "{83E4016D-5941-4735-AF88-422144619588}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -985,6 +987,10 @@ Global
{231F1581-AA21-44C3-BF27-51EB3AD5355C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{231F1581-AA21-44C3-BF27-51EB3AD5355C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{231F1581-AA21-44C3-BF27-51EB3AD5355C}.Release|Any CPU.Build.0 = Release|Any CPU
{83E4016D-5941-4735-AF88-422144619588}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{83E4016D-5941-4735-AF88-422144619588}.Debug|Any CPU.Build.0 = Debug|Any CPU
{83E4016D-5941-4735-AF88-422144619588}.Release|Any CPU.ActiveCfg = Release|Any CPU
{83E4016D-5941-4735-AF88-422144619588}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -1152,6 +1158,7 @@ Global
{C1D891B0-AE83-42CB-987D-425A2787DE78} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
{04F44063-C952-403A-815F-EFB778BDA125} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
{231F1581-AA21-44C3-BF27-51EB3AD5355C} = {447C8A77-E5F0-4538-8687-7383196D04EA}
{83E4016D-5941-4735-AF88-422144619588} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {BB97ECF4-9A84-433F-A80B-2A3285BDD1D5}

99
framework/src/Volo.Abp.AutoMapper/AutoMapper/AbpAutoMapperMultiLingualDtoExtensions.cs

@ -0,0 +1,99 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using Volo.Abp.Localization;
using Volo.Abp.MultiLingualEntities;
using Volo.Abp.Settings;
using Volo.Abp.Threading;
namespace AutoMapper
{
public static class AbpAutoMapperMultiLingualDtoExtensions
{
public static CreateMultiLingualMapResult<TMultiLingualEntity, TTranslation, TDestination> CreateMultLingualMap<
TMultiLingualEntity,
TTranslation, TDestination>(
this Profile profile,
ISettingProvider serviceProvider,
bool fallbackToParentCultures = false)
where TMultiLingualEntity : class, IMultiLingualEntity<TTranslation>
where TTranslation : class, IEntityTranslation
{
return new CreateMultiLingualMapResult<TMultiLingualEntity, TTranslation, TDestination>
{
TranslationMap = profile.CreateMap<TTranslation, TDestination>(),
EntityMap = profile.CreateMap<TMultiLingualEntity, TDestination>().BeforeMap(
(source, destination, context) =>
{
if (source.Translations == null || !source.Translations.Any())
{
return;
}
var translation =
source.Translations.FirstOrDefault(pt => pt.Language == CultureInfo.CurrentUICulture.Name);
if (translation != null)
{
context.Mapper.Map(translation, destination);
return;
}
if (fallbackToParentCultures)
{
translation =
GeTranslationBasedOnCulturalRecursive<TMultiLingualEntity, TTranslation>(
CultureInfo.CurrentUICulture.Parent, source.Translations, 0);
if (translation != null)
{
context.Mapper.Map(translation, destination);
return;
}
}
var defaultLanguage = AsyncHelper.RunSync(() =>
serviceProvider.GetOrNullAsync(LocalizationSettingNames.DefaultLanguage));
translation = source.Translations.FirstOrDefault(pt => pt.Language == defaultLanguage);
if (translation != null)
{
context.Mapper.Map(translation, destination);
return;
}
translation = source.Translations.FirstOrDefault();
if (translation != null)
{
context.Mapper.Map(translation, destination);
}
})
};
}
private const int MaxCultureFallbackDepth = 5;
private static TTranslation GeTranslationBasedOnCulturalRecursive<TMultiLingualEntity, TTranslation>(
CultureInfo culture, ICollection<TTranslation> translations, int currentDepth)
where TTranslation : class, IEntityTranslation
{
if (culture == null || culture.Name.IsNullOrWhiteSpace() || translations.IsNullOrEmpty() ||
currentDepth > MaxCultureFallbackDepth)
{
return null;
}
var translation = translations.FirstOrDefault(pt =>
pt.Language.Equals(culture.Name, StringComparison.OrdinalIgnoreCase));
return translation ??
GeTranslationBasedOnCulturalRecursive<TMultiLingualEntity, TTranslation>(culture.Parent,
translations, currentDepth + 1);
}
}
public class CreateMultiLingualMapResult<TMultiLingualEntity, TTranslation, TDestination>
{
public IMappingExpression<TTranslation, TDestination> TranslationMap { get; set; }
public IMappingExpression<TMultiLingualEntity, TDestination> EntityMap { get; set; }
}
}

1
framework/src/Volo.Abp.AutoMapper/Volo.Abp.AutoMapper.csproj

@ -18,6 +18,7 @@
<ProjectReference Include="..\Volo.Abp.Auditing\Volo.Abp.Auditing.csproj" />
<ProjectReference Include="..\Volo.Abp.ObjectExtending\Volo.Abp.ObjectExtending.csproj" />
<ProjectReference Include="..\Volo.Abp.ObjectMapping\Volo.Abp.ObjectMapping.csproj" />
<ProjectReference Include="..\Volo.Abp.MultiLingualEntities\Volo.Abp.MultiLingualEntities.csproj" />
</ItemGroup>
<ItemGroup>

1
framework/src/Volo.Abp.Ddd.Domain/Volo.Abp.Ddd.Domain.csproj

@ -24,6 +24,7 @@
<ProjectReference Include="..\Volo.Abp.Threading\Volo.Abp.Threading.csproj" />
<ProjectReference Include="..\Volo.Abp.Timing\Volo.Abp.Timing.csproj" />
<ProjectReference Include="..\Volo.Abp.Uow\Volo.Abp.Uow.csproj" />
<ProjectReference Include="..\Volo.Abp.MultiLingualEntities\Volo.Abp.MultiLingualEntities.csproj" />
</ItemGroup>
</Project>

21
framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/Modeling/AbpEntityTypeBuilderExtensions.cs

@ -7,6 +7,7 @@ using Volo.Abp.Data;
using Volo.Abp.Domain.Entities;
using Volo.Abp.EntityFrameworkCore.ValueComparers;
using Volo.Abp.EntityFrameworkCore.ValueConverters;
using Volo.Abp.MultiLingualEntities;
using Volo.Abp.MultiTenancy;
using Volo.Abp.ObjectExtending;
@ -28,6 +29,7 @@ namespace Volo.Abp.EntityFrameworkCore.Modeling
b.TryConfigureLastModificationTime();
b.TryConfigureModificationAudited();
b.TryConfigureMultiTenant();
b.TryConfigureEntityTranslation();
}
public static void ConfigureConcurrencyStamp<T>(this EntityTypeBuilder<T> b)
@ -302,6 +304,25 @@ namespace Volo.Abp.EntityFrameworkCore.Modeling
b.As<EntityTypeBuilder>().TryConfigureConcurrencyStamp();
}
public static void ConfigureMultiLingual<T, TTranslation>(this EntityTypeBuilder<T> b)
where T : class, IMultiLingualEntity<TTranslation>
where TTranslation : class, IEntityTranslation
{
b.As<EntityTypeBuilder>().TryConfigureEntityTranslation();
}
public static void TryConfigureEntityTranslation(this EntityTypeBuilder b)
{
if (b.Metadata.ClrType.IsAssignableTo<IEntityTranslation>())
{
b.HasIndex(nameof(IEntityTranslation.Language))
.IsUnique();
b.Property(nameof(IEntityTranslation.Language))
.IsRequired()
.HasColumnName(nameof(IEntityTranslation.Language));
}
}
//TODO: Add other interfaces (IAuditedObject<TUser>...)
}
}

3
framework/src/Volo.Abp.MultiLingualEntities/FodyWeavers.xml

@ -0,0 +1,3 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<ConfigureAwait ContinueOnCapturedContext="false" />
</Weavers>

30
framework/src/Volo.Abp.MultiLingualEntities/FodyWeavers.xsd

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
<xs:element name="Weavers">
<xs:complexType>
<xs:all>
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" />
</xs:complexType>
</xs:element>
</xs:all>
<xs:attribute name="VerifyAssembly" type="xs:boolean">
<xs:annotation>
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
<xs:annotation>
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="GenerateXsd" type="xs:boolean">
<xs:annotation>
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:schema>

11
framework/src/Volo.Abp.MultiLingualEntities/Volo.Abp.MultiLingualEntities.csproj

@ -0,0 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\configureawait.props" />
<Import Project="..\..\..\common.props" />
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace />
</PropertyGroup>
</Project>

19
framework/src/Volo.Abp.MultiLingualEntities/Volo/Abp/MultiLingualEntities/IEntityTranslation.cs

@ -0,0 +1,19 @@
namespace Volo.Abp.MultiLingualEntities
{
public interface IEntityTranslation
{
string Language { get; set; }
}
public interface IEntityTranslation<TEntity, TPrimaryKeyOfMultiLingualEntity> : IEntityTranslation
{
TEntity Core { get; set; }
TPrimaryKeyOfMultiLingualEntity CoreId { get; set; }
}
public interface IEntityTranslation<TEntity>: IEntityTranslation<TEntity, int>
{
}
}

10
framework/src/Volo.Abp.MultiLingualEntities/Volo/Abp/MultiLingualEntities/IMultiLingualEntity.cs

@ -0,0 +1,10 @@
using System.Collections.Generic;
namespace Volo.Abp.MultiLingualEntities
{
public interface IMultiLingualEntity<TTranslation>
where TTranslation : class, IEntityTranslation
{
ICollection<TTranslation> Translations { get; set; }
}
}
Loading…
Cancel
Save