Skip to content

Commit

Permalink
Redesign multi-lingual
Browse files Browse the repository at this point in the history
  • Loading branch information
realLiangshiwei committed Sep 3, 2020
1 parent 41dba35 commit dcf7812
Show file tree
Hide file tree
Showing 26 changed files with 468 additions and 137 deletions.
14 changes: 14 additions & 0 deletions framework/Volo.Abp.sln
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,10 @@ 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.MultiLingualObject", "src\Volo.Abp.MultiLingualObject\Volo.Abp.MultiLingualObject.csproj", "{C9142DED-1F6C-4385-A37D-81E46B233306}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.MultiLingualObject.Tests", "test\Volo.Abp.MultiLingualObject.Tests\Volo.Abp.MultiLingualObject.Tests.csproj", "{A30D63B0-E952-4052-BAEE-38B8BF924093}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -985,6 +989,14 @@ 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
{C9142DED-1F6C-4385-A37D-81E46B233306}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C9142DED-1F6C-4385-A37D-81E46B233306}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C9142DED-1F6C-4385-A37D-81E46B233306}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C9142DED-1F6C-4385-A37D-81E46B233306}.Release|Any CPU.Build.0 = Release|Any CPU
{A30D63B0-E952-4052-BAEE-38B8BF924093}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A30D63B0-E952-4052-BAEE-38B8BF924093}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A30D63B0-E952-4052-BAEE-38B8BF924093}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A30D63B0-E952-4052-BAEE-38B8BF924093}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -1152,6 +1164,8 @@ 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}
{C9142DED-1F6C-4385-A37D-81E46B233306} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
{A30D63B0-E952-4052-BAEE-38B8BF924093} = {447C8A77-E5F0-4538-8687-7383196D04EA}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {BB97ECF4-9A84-433F-A80B-2A3285BDD1D5}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,99 +1,66 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using Volo.Abp.Domain.Entities;
using Volo.Abp.Localization;
using Volo.Abp.DependencyInjection;
using Volo.Abp.MultiLingualObject;
using Volo.Abp.Settings;
using Volo.Abp.Threading;

namespace AutoMapper
{
public static class AbpAutoMapperMultiLingualDtoExtensions
{
public static CreateMultiLingualMapResult<TMultiLingualEntity, TTranslation, TDestination> CreateMultLingualMap<
TMultiLingualEntity,
public static CreateMultiLingualMapResult<TSource, TTranslation, TDestination> MapMultiLingual<TSource,
TTranslation, TDestination>(
this Profile profile,
ISettingProvider serviceProvider,
this IMappingExpression<TSource, TDestination> mappingExpression,
Profile profile,
bool fallbackToParentCultures = false)
where TMultiLingualEntity : class, IMultiLingualEntity<TTranslation>
where TTranslation : class, IEntityTranslation
where TDestination : class
where TSource : IHasMultiLingual<TTranslation>
where TTranslation : class, IMultiLingualTranslation
{
return new CreateMultiLingualMapResult<TMultiLingualEntity, TTranslation, TDestination>
return new CreateMultiLingualMapResult<TSource, TTranslation, TDestination>
{
TranslationMap = profile.CreateMap<TTranslation, TDestination>(),
EntityMap = profile.CreateMap<TMultiLingualEntity, TDestination>().BeforeMap(
(source, destination, context) =>
{
if (source.Translations == null || !source.Translations.Any())
{
return;
}
EntityMap = mappingExpression.BeforeMap(((source, destination, context) =>
{
var mapperAction =
(AbpAutoMapperMultiLingualObjectAction<TSource, TTranslation, TDestination>) context.Options
.ServiceCtor(
typeof(AbpAutoMapperMultiLingualObjectAction<TSource, TTranslation, TDestination>));
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;
}
}
mapperAction.FallbackToParentCultures = fallbackToParentCultures;
mapperAction.Process(source, destination, context);
}))
};
}
}

var defaultLanguage = AsyncHelper.RunSync(() =>
serviceProvider.GetOrNullAsync(LocalizationSettingNames.DefaultLanguage));
public class AbpAutoMapperMultiLingualObjectAction<TMultiLingual, TTranslation, TDestination>
: IMappingAction<TMultiLingual, TDestination>, ITransientDependency
where TMultiLingual : IHasMultiLingual<TTranslation>
where TTranslation : class, IMultiLingualTranslation
{
private readonly ISettingProvider _settingProvider;

translation = source.Translations.FirstOrDefault(pt => pt.Language == defaultLanguage);
if (translation != null)
{
context.Mapper.Map(translation, destination);
return;
}
public bool FallbackToParentCultures { get; set; }

translation = source.Translations.FirstOrDefault();
if (translation != null)
{
context.Mapper.Map(translation, destination);
}
})
};
public AbpAutoMapperMultiLingualObjectAction(ISettingProvider settingProvider)
{
_settingProvider = settingProvider;
}

private const int MaxCultureFallbackDepth = 5;

private static TTranslation GeTranslationBasedOnCulturalRecursive<TMultiLingualEntity, TTranslation>(
CultureInfo culture, ICollection<TTranslation> translations, int currentDepth)
where TTranslation : class, IEntityTranslation
public void Process(TMultiLingual source, TDestination destination, ResolutionContext context)
{
if (culture == null || culture.Name.IsNullOrWhiteSpace() || translations.IsNullOrEmpty() ||
currentDepth > MaxCultureFallbackDepth)
var translation = source.GetMultiLingualTranslation(_settingProvider, FallbackToParentCultures);

if (translation != null)
{
return null;
context.Mapper.Map(translation, destination);
}

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 class CreateMultiLingualMapResult<TMultiLingual, TTranslation, TDestination>
{
public IMappingExpression<TTranslation, TDestination> TranslationMap { get; set; }

public IMappingExpression<TMultiLingualEntity, TDestination> EntityMap { get; set; }
public IMappingExpression<TMultiLingual, TDestination> EntityMap { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

<ItemGroup>
<ProjectReference Include="..\Volo.Abp.Auditing\Volo.Abp.Auditing.csproj" />
<ProjectReference Include="..\Volo.Abp.MultiLingualObject\Volo.Abp.MultiLingualObject.csproj" />
<ProjectReference Include="..\Volo.Abp.ObjectExtending\Volo.Abp.ObjectExtending.csproj" />
<ProjectReference Include="..\Volo.Abp.ObjectMapping\Volo.Abp.ObjectMapping.csproj" />
<ProjectReference Include="..\Volo.Abp.Ddd.Domain\Volo.Abp.Ddd.Domain.csproj" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using Microsoft.Extensions.Options;
using Volo.Abp.Auditing;
using Volo.Abp.Modularity;
using Volo.Abp.MultiLingualObject;
using Volo.Abp.ObjectExtending;
using Volo.Abp.ObjectMapping;

Expand All @@ -12,7 +13,8 @@ namespace Volo.Abp.AutoMapper
[DependsOn(
typeof(AbpObjectMappingModule),
typeof(AbpObjectExtendingModule),
typeof(AbpAuditingModule)
typeof(AbpAuditingModule),
typeof(AbpMultiLingualObjectModule)
)]
public class AbpAutoMapperModule : AbpModule
{
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
<ItemGroup>
<ProjectReference Include="..\Volo.Abp.Ddd.Domain\Volo.Abp.Ddd.Domain.csproj" />
<ProjectReference Include="..\Volo.Abp.Json\Volo.Abp.Json.csproj" />
<ProjectReference Include="..\Volo.Abp.MultiLingualObject\Volo.Abp.MultiLingualObject.csproj" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using Volo.Abp.Domain.Entities;
using Volo.Abp.EntityFrameworkCore.ValueComparers;
using Volo.Abp.EntityFrameworkCore.ValueConverters;
using Volo.Abp.MultiLingualObject;
using Volo.Abp.MultiTenancy;
using Volo.Abp.ObjectExtending;

Expand Down Expand Up @@ -304,21 +305,21 @@ public static void ConfigureFullAuditedAggregateRoot<T>(this EntityTypeBuilder<T
}

public static void ConfigureMultiLingual<T, TTranslation>(this EntityTypeBuilder<T> b)
where T : class, IMultiLingualEntity<TTranslation>
where TTranslation : class, IEntityTranslation
where T : class, IHasMultiLingual<TTranslation>
where TTranslation : class, IMultiLingualTranslation
{
b.As<EntityTypeBuilder>().TryConfigureEntityTranslation();
}

public static void TryConfigureEntityTranslation(this EntityTypeBuilder b)
{
if (b.Metadata.ClrType.IsAssignableTo<IEntityTranslation>())
if (b.Metadata.ClrType.IsAssignableTo<IMultiLingualTranslation>())
{
b.HasIndex(nameof(IEntityTranslation.Language))
b.HasIndex(nameof(IMultiLingualTranslation.Language))
.IsUnique();
b.Property(nameof(IEntityTranslation.Language))
b.Property(nameof(IMultiLingualTranslation.Language))
.IsRequired()
.HasColumnName(nameof(IEntityTranslation.Language));
.HasColumnName(nameof(IMultiLingualTranslation.Language));
}
}

Expand Down
3 changes: 3 additions & 0 deletions framework/src/Volo.Abp.MultiLingualObject/FodyWeavers.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<ConfigureAwait ContinueOnCapturedContext="false" />
</Weavers>
30 changes: 30 additions & 0 deletions framework/src/Volo.Abp.MultiLingualObject/FodyWeavers.xsd
Original file line number Diff line number Diff line change
@@ -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>
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">

<Import Project="..\..\..\configureawait.props" />
<Import Project="..\..\..\common.props" />

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace />
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\Volo.Abp.Localization\Volo.Abp.Localization.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using Volo.Abp.Localization;
using Volo.Abp.Modularity;

namespace Volo.Abp.MultiLingualObject
{
[DependsOn(
typeof(AbpLocalizationModule))]
public class AbpMultiLingualObjectModule : AbpModule
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using System.Collections.Generic;

namespace Volo.Abp.MultiLingualObject
{
public interface IHasMultiLingual<TTranslation>
where TTranslation : class, IMultiLingualTranslation
{
ICollection<TTranslation> Translations { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
namespace Volo.Abp.MultiLingualObject
{
public interface IMultiLingualTranslation
{
string Language { get; set; }
}

public interface IMultiLingualTranslation<T, TPrimaryKeyOfMultiLingualObject> : IMultiLingualTranslation
where T : class
{
T Core { get; set; }

TPrimaryKeyOfMultiLingualObject CoreId { get; set; }
}
}

0 comments on commit dcf7812

Please sign in to comment.