mirror of https://github.com/abpframework/abp.git
committed by
GitHub
25 changed files with 681 additions and 4 deletions
@ -0,0 +1,54 @@ |
|||||
|
using Volo.Abp.MultiLingualObject; |
||||
|
using Volo.Abp.Threading; |
||||
|
|
||||
|
namespace AutoMapper |
||||
|
{ |
||||
|
public static class AbpAutoMapperMultiLingualDtoExtensions |
||||
|
{ |
||||
|
public static CreateMultiLingualMapResult<TSource, TTranslation, TDestination> CreateMultiLingualMap<TSource, TTranslation, TDestination>(this Profile profile) |
||||
|
where TTranslation : class, IMultiLingualTranslation |
||||
|
where TSource : IHasMultiLingual<TTranslation> |
||||
|
{ |
||||
|
|
||||
|
return new( |
||||
|
profile.CreateMap<TSource, TDestination>().BeforeMap<AbpMultiLingualMapperAction<TSource, TTranslation, TDestination>>(), |
||||
|
profile.CreateMap<TTranslation, TDestination>()); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public class AbpMultiLingualMapperAction<TSource, TTranslation, TDestination> : IMappingAction<TSource, TDestination> |
||||
|
where TTranslation : class, IMultiLingualTranslation |
||||
|
where TSource : IHasMultiLingual<TTranslation> |
||||
|
{ |
||||
|
private readonly IMultiLingualObjectManager _multiLingualObjectManager; |
||||
|
|
||||
|
public AbpMultiLingualMapperAction(IMultiLingualObjectManager multiLingualObjectManager) |
||||
|
{ |
||||
|
_multiLingualObjectManager = multiLingualObjectManager; |
||||
|
} |
||||
|
|
||||
|
public void Process(TSource source, TDestination destination, ResolutionContext context) |
||||
|
{ |
||||
|
var translation = AsyncHelper.RunSync(() => _multiLingualObjectManager.GetTranslationAsync<TSource, TTranslation>(source)); |
||||
|
if (translation != null) |
||||
|
{ |
||||
|
context.Mapper.Map(translation, destination); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public class CreateMultiLingualMapResult<TSource, TTranslation, TDestination> |
||||
|
{ |
||||
|
public IMappingExpression<TSource, TDestination> EntityMap { get; } |
||||
|
|
||||
|
public IMappingExpression<TTranslation, TDestination> TranslateMap { get; } |
||||
|
|
||||
|
public CreateMultiLingualMapResult( |
||||
|
IMappingExpression<TSource, TDestination> entityMap, |
||||
|
IMappingExpression<TTranslation, TDestination> translateMap) |
||||
|
{ |
||||
|
EntityMap = entityMap; |
||||
|
TranslateMap = translateMap; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,3 @@ |
|||||
|
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
||||
|
<ConfigureAwait ContinueOnCapturedContext="false" /> |
||||
|
</Weavers> |
||||
@ -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> |
||||
@ -0,0 +1,21 @@ |
|||||
|
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
|
<Import Project="..\..\..\configureawait.props" /> |
||||
|
<Import Project="..\..\..\common.props" /> |
||||
|
|
||||
|
<PropertyGroup> |
||||
|
<TargetFramework>netstandard2.0</TargetFramework> |
||||
|
<AssemblyName>Volo.Abp.MultiLingualObject</AssemblyName> |
||||
|
<PackageId>Volo.Abp.MultiLingualObject</PackageId> |
||||
|
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback> |
||||
|
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> |
||||
|
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> |
||||
|
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> |
||||
|
<RootNamespace /> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<ProjectReference Include="..\Volo.Abp.Localization\Volo.Abp.Localization.csproj" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
</Project> |
||||
@ -0,0 +1,11 @@ |
|||||
|
using Volo.Abp.Localization; |
||||
|
using Volo.Abp.Modularity; |
||||
|
|
||||
|
namespace Volo.Abp.MultiLingualObject |
||||
|
{ |
||||
|
[DependsOn( |
||||
|
typeof(AbpLocalizationModule))] |
||||
|
public class AbpMultiLingualObjectModule : AbpModule |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
@ -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; } |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,21 @@ |
|||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
namespace Volo.Abp.MultiLingualObject |
||||
|
{ |
||||
|
public interface IMultiLingualObjectManager |
||||
|
{ |
||||
|
TTranslation GetTranslation<TMultiLingual, TTranslation>( |
||||
|
TMultiLingual multiLingual, |
||||
|
bool fallbackToParentCultures = true, |
||||
|
string culture = null) |
||||
|
where TMultiLingual : IHasMultiLingual<TTranslation> |
||||
|
where TTranslation : class, IMultiLingualTranslation; |
||||
|
|
||||
|
Task<TTranslation> GetTranslationAsync<TMultiLingual, TTranslation>( |
||||
|
TMultiLingual multiLingual, |
||||
|
bool fallbackToParentCultures = true, |
||||
|
string culture = null) |
||||
|
where TMultiLingual : IHasMultiLingual<TTranslation> |
||||
|
where TTranslation : class, IMultiLingualTranslation; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,7 @@ |
|||||
|
namespace Volo.Abp.MultiLingualObject |
||||
|
{ |
||||
|
public interface IMultiLingualTranslation |
||||
|
{ |
||||
|
string Language { get; set; } |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,95 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Globalization; |
||||
|
using System.Linq; |
||||
|
using System.Threading.Tasks; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
using Volo.Abp.Localization; |
||||
|
using Volo.Abp.Settings; |
||||
|
using Volo.Abp.Threading; |
||||
|
|
||||
|
namespace Volo.Abp.MultiLingualObject |
||||
|
{ |
||||
|
public class MultiLingualObjectManager : IMultiLingualObjectManager, ITransientDependency |
||||
|
{ |
||||
|
protected ISettingProvider SettingProvider { get; } |
||||
|
|
||||
|
protected const int MaxCultureFallbackDepth = 5; |
||||
|
|
||||
|
public MultiLingualObjectManager(ISettingProvider settingProvider) |
||||
|
{ |
||||
|
SettingProvider = settingProvider; |
||||
|
} |
||||
|
|
||||
|
public TTranslation GetTranslation<TMultiLingual, TTranslation>( |
||||
|
TMultiLingual multiLingual, |
||||
|
bool fallbackToParentCultures = true, |
||||
|
string culture = null) |
||||
|
where TMultiLingual : IHasMultiLingual<TTranslation> |
||||
|
where TTranslation : class, IMultiLingualTranslation |
||||
|
{ |
||||
|
return AsyncHelper.RunSync(() => |
||||
|
GetTranslationAsync<TMultiLingual, TTranslation>(multiLingual, fallbackToParentCultures, culture)); |
||||
|
} |
||||
|
|
||||
|
public virtual async Task<TTranslation> GetTranslationAsync<TMultiLingual, TTranslation>( |
||||
|
TMultiLingual multiLingual, |
||||
|
bool fallbackToParentCultures = true, |
||||
|
string culture = null) |
||||
|
where TMultiLingual : IHasMultiLingual<TTranslation> |
||||
|
where TTranslation : class, IMultiLingualTranslation |
||||
|
{ |
||||
|
culture ??= CultureInfo.CurrentUICulture.Name; |
||||
|
|
||||
|
if (multiLingual.Translations == null || !multiLingual.Translations.Any()) |
||||
|
{ |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
var translation = multiLingual.Translations.FirstOrDefault(pt => pt.Language == culture); |
||||
|
if (translation != null) |
||||
|
{ |
||||
|
return translation; |
||||
|
} |
||||
|
|
||||
|
if (fallbackToParentCultures) |
||||
|
{ |
||||
|
translation = |
||||
|
GeTranslationBasedOnCulturalRecursive( |
||||
|
CultureInfo.CurrentUICulture.Parent, multiLingual.Translations, 0); |
||||
|
if (translation != null) |
||||
|
{ |
||||
|
return translation; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
var defaultLanguage = await SettingProvider.GetOrNullAsync(LocalizationSettingNames.DefaultLanguage); |
||||
|
|
||||
|
translation = multiLingual.Translations.FirstOrDefault(pt => pt.Language == defaultLanguage); |
||||
|
if (translation != null) |
||||
|
{ |
||||
|
return translation; |
||||
|
} |
||||
|
|
||||
|
translation = multiLingual.Translations.FirstOrDefault(); |
||||
|
return translation; |
||||
|
} |
||||
|
|
||||
|
protected virtual TTranslation GeTranslationBasedOnCulturalRecursive<TTranslation>( |
||||
|
CultureInfo culture, ICollection<TTranslation> translations, int currentDepth) |
||||
|
where TTranslation : class, IMultiLingualTranslation |
||||
|
{ |
||||
|
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(culture.Parent, |
||||
|
translations, currentDepth + 1); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,114 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Shouldly; |
||||
|
using Volo.Abp; |
||||
|
using Volo.Abp.AutoMapper; |
||||
|
using Volo.Abp.Localization; |
||||
|
using Volo.Abp.MultiLingualObject.TestObjects; |
||||
|
using Volo.Abp.Testing; |
||||
|
using Xunit; |
||||
|
|
||||
|
namespace AutoMapper |
||||
|
{ |
||||
|
public class AbpAutoMapperMultiLingualDto_Tests : AbpIntegratedTest<AutoMapperTestModule> |
||||
|
{ |
||||
|
private readonly Volo.Abp.ObjectMapping.IObjectMapper _objectMapper; |
||||
|
private readonly MultiLingualBook _book; |
||||
|
|
||||
|
public AbpAutoMapperMultiLingualDto_Tests() |
||||
|
{ |
||||
|
_objectMapper = ServiceProvider.GetRequiredService<Volo.Abp.ObjectMapping.IObjectMapper>(); |
||||
|
|
||||
|
var id = Guid.NewGuid(); |
||||
|
_book = new MultiLingualBook(id, 100) |
||||
|
{ |
||||
|
Translations = new List<MultiLingualBookTranslation>() |
||||
|
}; |
||||
|
|
||||
|
var en = new MultiLingualBookTranslation |
||||
|
{ |
||||
|
Language = "en", |
||||
|
Name = "C# in Depth", |
||||
|
}; |
||||
|
var zh = new MultiLingualBookTranslation |
||||
|
{ |
||||
|
Language = "zh-Hans", |
||||
|
Name = "深入理解C#", |
||||
|
}; |
||||
|
|
||||
|
_book.Translations.Add(en); |
||||
|
_book.Translations.Add(zh); |
||||
|
} |
||||
|
|
||||
|
protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options) |
||||
|
{ |
||||
|
options.UseAutofac(); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Should_Map_Current_UI_Culture() |
||||
|
{ |
||||
|
using (CultureHelper.Use("zh-Hans")) |
||||
|
{ |
||||
|
var bookDto = _objectMapper.Map<MultiLingualBook, MultiLingualBookDto>(_book); |
||||
|
|
||||
|
bookDto.Name.ShouldBe("深入理解C#"); |
||||
|
bookDto.Price.ShouldBe(_book.Price); |
||||
|
bookDto.Id.ShouldBe(_book.Id); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Should_Map_Fallback_UI_Culture() |
||||
|
{ |
||||
|
using (CultureHelper.Use("en-us")) |
||||
|
{ |
||||
|
var bookDto = _objectMapper.Map<MultiLingualBook, MultiLingualBookDto>(_book); |
||||
|
|
||||
|
bookDto.Name.ShouldBe("C# in Depth"); |
||||
|
bookDto.Price.ShouldBe(_book.Price); |
||||
|
bookDto.Id.ShouldBe(_book.Id); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Should_Map_Default_Language() |
||||
|
{ |
||||
|
using (CultureHelper.Use("tr")) |
||||
|
{ |
||||
|
var bookDto = _objectMapper.Map<MultiLingualBook, MultiLingualBookDto>(_book); |
||||
|
|
||||
|
bookDto.Name.ShouldBe("C# in Depth"); |
||||
|
bookDto.Price.ShouldBe(_book.Price); |
||||
|
bookDto.Id.ShouldBe(_book.Id); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void NoTranslations_ShouldStillMapObject() |
||||
|
{ |
||||
|
_book.Translations.Clear(); |
||||
|
|
||||
|
using (CultureHelper.Use("tr")) |
||||
|
{ |
||||
|
var bookDto = _objectMapper.Map<MultiLingualBook, MultiLingualBookDto>(_book); |
||||
|
|
||||
|
bookDto.Name.ShouldBeNull(); |
||||
|
bookDto.Price.ShouldBe(_book.Price); |
||||
|
bookDto.Id.ShouldBe(_book.Id); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public class BookProfile : Profile |
||||
|
{ |
||||
|
public BookProfile() |
||||
|
{ |
||||
|
var mapResult = this.CreateMultiLingualMap<MultiLingualBook, MultiLingualBookTranslation, MultiLingualBookDto>(); |
||||
|
|
||||
|
mapResult.EntityMap.ValidateMemberList(MemberList.None); |
||||
|
mapResult.TranslateMap.ValidateMemberList(MemberList.None); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,18 @@ |
|||||
|
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
|
<Import Project="..\..\..\common.test.props" /> |
||||
|
|
||||
|
<PropertyGroup> |
||||
|
<TargetFramework>net5.0</TargetFramework> |
||||
|
<RootNamespace /> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<ProjectReference Include="..\..\src\Volo.Abp.Autofac\Volo.Abp.Autofac.csproj" /> |
||||
|
<ProjectReference Include="..\..\src\Volo.Abp.MultiLingualObject\Volo.Abp.MultiLingualObject.csproj" /> |
||||
|
<ProjectReference Include="..\..\src\Volo.Abp.ObjectMapping\Volo.Abp.ObjectMapping.csproj" /> |
||||
|
<ProjectReference Include="..\AbpTestBase\AbpTestBase.csproj" /> |
||||
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(MicrosoftNETTestSdkPackageVersion)" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
</Project> |
||||
@ -0,0 +1,21 @@ |
|||||
|
using Autofac.Extensions.DependencyInjection; |
||||
|
using Volo.Abp.Autofac; |
||||
|
using Volo.Abp.Localization; |
||||
|
using Volo.Abp.Modularity; |
||||
|
using Volo.Abp.ObjectMapping; |
||||
|
using Volo.Abp.Settings; |
||||
|
|
||||
|
namespace Volo.Abp.MultiLingualObject |
||||
|
{ |
||||
|
[DependsOn( |
||||
|
typeof(AbpAutofacModule), |
||||
|
typeof(AbpLocalizationModule), |
||||
|
typeof(AbpSettingsModule), |
||||
|
typeof(AbpObjectMappingModule), |
||||
|
typeof(AbpMultiLingualObjectModule), |
||||
|
typeof(AbpTestBaseModule) |
||||
|
)] |
||||
|
public class AbpMultiLingualObjectTestModule : AbpModule |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,76 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Threading.Tasks; |
||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Shouldly; |
||||
|
using Volo.Abp.Localization; |
||||
|
using Volo.Abp.MultiLingualObject.TestObjects; |
||||
|
using Volo.Abp.Testing; |
||||
|
using Xunit; |
||||
|
|
||||
|
namespace Volo.Abp.MultiLingualObject |
||||
|
{ |
||||
|
public class MultiLingualObjectManager_Tests : AbpIntegratedTest<AbpMultiLingualObjectTestModule> |
||||
|
{ |
||||
|
private readonly IMultiLingualObjectManager _multiLingualObjectManager; |
||||
|
private readonly MultiLingualBook _book; |
||||
|
|
||||
|
public MultiLingualObjectManager_Tests() |
||||
|
{ |
||||
|
_multiLingualObjectManager = ServiceProvider.GetRequiredService<IMultiLingualObjectManager>(); |
||||
|
|
||||
|
var id = Guid.NewGuid(); |
||||
|
_book = new MultiLingualBook(id, 100) |
||||
|
{ |
||||
|
Translations = new List<MultiLingualBookTranslation>() |
||||
|
}; |
||||
|
|
||||
|
var en = new MultiLingualBookTranslation |
||||
|
{ |
||||
|
Language = "en", |
||||
|
Name = "C# in Depth", |
||||
|
}; |
||||
|
var zh = new MultiLingualBookTranslation |
||||
|
{ |
||||
|
Language = "zh-Hans", |
||||
|
Name = "深入理解C#", |
||||
|
}; |
||||
|
|
||||
|
_book.Translations.Add(en); |
||||
|
_book.Translations.Add(zh); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void GetTranslation() |
||||
|
{ |
||||
|
using (CultureHelper.Use("en-us")) |
||||
|
{ |
||||
|
var translation = _multiLingualObjectManager.GetTranslation<MultiLingualBook, MultiLingualBookTranslation>(_book); |
||||
|
|
||||
|
translation.Name.ShouldBe("C# in Depth"); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public async Task GetTranslationAsync() |
||||
|
{ |
||||
|
using (CultureHelper.Use("en-us")) |
||||
|
{ |
||||
|
var translation = await _multiLingualObjectManager.GetTranslationAsync<MultiLingualBook, MultiLingualBookTranslation>(_book); |
||||
|
|
||||
|
translation.Name.ShouldBe("C# in Depth"); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public async Task Should_Get_Specified_Language() |
||||
|
{ |
||||
|
using (CultureHelper.Use("zh-Hans")) |
||||
|
{ |
||||
|
var translation = await _multiLingualObjectManager.GetTranslationAsync<MultiLingualBook, MultiLingualBookTranslation>(_book, culture: "en"); |
||||
|
|
||||
|
translation.Name.ShouldBe("C# in Depth"); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,132 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Shouldly; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
using Volo.Abp.Localization; |
||||
|
using Volo.Abp.MultiLingualObject.TestObjects; |
||||
|
using Volo.Abp.ObjectMapping; |
||||
|
using Volo.Abp.Testing; |
||||
|
using Xunit; |
||||
|
|
||||
|
namespace Volo.Abp.MultiLingualObject |
||||
|
{ |
||||
|
public class MultiLingualObject_Tests : AbpIntegratedTest<AbpMultiLingualObjectTestModule> |
||||
|
{ |
||||
|
private readonly IObjectMapper _objectMapper; |
||||
|
private readonly MultiLingualBook _book; |
||||
|
|
||||
|
public MultiLingualObject_Tests() |
||||
|
{ |
||||
|
_objectMapper = ServiceProvider.GetRequiredService<IObjectMapper>(); |
||||
|
|
||||
|
var id = Guid.NewGuid(); |
||||
|
_book = new MultiLingualBook(id, 100) |
||||
|
{ |
||||
|
Translations = new List<MultiLingualBookTranslation>() |
||||
|
}; |
||||
|
|
||||
|
var en = new MultiLingualBookTranslation |
||||
|
{ |
||||
|
Language = "en", |
||||
|
Name = "C# in Depth", |
||||
|
}; |
||||
|
var zh = new MultiLingualBookTranslation |
||||
|
{ |
||||
|
Language = "zh-Hans", |
||||
|
Name = "深入理解C#", |
||||
|
}; |
||||
|
|
||||
|
_book.Translations.Add(en); |
||||
|
_book.Translations.Add(zh); |
||||
|
} |
||||
|
|
||||
|
protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options) |
||||
|
{ |
||||
|
options.UseAutofac(); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Should_Map_Current_UI_Culture() |
||||
|
{ |
||||
|
using (CultureHelper.Use("zh-Hans")) |
||||
|
{ |
||||
|
var bookDto = _objectMapper.Map<MultiLingualBook, MultiLingualBookDto>(_book); |
||||
|
|
||||
|
bookDto.Name.ShouldBe("深入理解C#"); |
||||
|
bookDto.Price.ShouldBe(_book.Price); |
||||
|
bookDto.Id.ShouldBe(_book.Id); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Should_Map_Fallback_UI_Culture() |
||||
|
{ |
||||
|
using (CultureHelper.Use("en-us")) |
||||
|
{ |
||||
|
var bookDto = _objectMapper.Map<MultiLingualBook, MultiLingualBookDto>(_book); |
||||
|
|
||||
|
bookDto.Name.ShouldBe("C# in Depth"); |
||||
|
bookDto.Price.ShouldBe(_book.Price); |
||||
|
bookDto.Id.ShouldBe(_book.Id); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Should_Map_Default_Language() |
||||
|
{ |
||||
|
using (CultureHelper.Use("tr")) |
||||
|
{ |
||||
|
var bookDto = _objectMapper.Map<MultiLingualBook, MultiLingualBookDto>(_book); |
||||
|
|
||||
|
bookDto.Name.ShouldBe("C# in Depth"); |
||||
|
bookDto.Price.ShouldBe(_book.Price); |
||||
|
bookDto.Id.ShouldBe(_book.Id); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void NoTranslations_ShouldStillMapObject() |
||||
|
{ |
||||
|
_book.Translations.Clear(); |
||||
|
|
||||
|
using (CultureHelper.Use("tr")) |
||||
|
{ |
||||
|
var bookDto = _objectMapper.Map<MultiLingualBook, MultiLingualBookDto>(_book); |
||||
|
|
||||
|
bookDto.Name.ShouldBeNull(); |
||||
|
bookDto.Price.ShouldBe(_book.Price); |
||||
|
bookDto.Id.ShouldBe(_book.Id); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public class MultiLingualBookObjectMapper : IObjectMapper<MultiLingualBook, MultiLingualBookDto>, |
||||
|
ITransientDependency |
||||
|
{ |
||||
|
private readonly IMultiLingualObjectManager _multiLingualObjectManager; |
||||
|
|
||||
|
public MultiLingualBookObjectMapper(IMultiLingualObjectManager multiLingualObjectManager) |
||||
|
{ |
||||
|
_multiLingualObjectManager = multiLingualObjectManager; |
||||
|
} |
||||
|
|
||||
|
public MultiLingualBookDto Map(MultiLingualBook source) |
||||
|
{ |
||||
|
var translation = |
||||
|
_multiLingualObjectManager.GetTranslation<MultiLingualBook, MultiLingualBookTranslation>(source); |
||||
|
|
||||
|
return new MultiLingualBookDto |
||||
|
{ |
||||
|
Price = source.Price, |
||||
|
Id = source.Id, |
||||
|
Name = translation?.Name |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
public MultiLingualBookDto Map(MultiLingualBook source, MultiLingualBookDto destination) |
||||
|
{ |
||||
|
return default; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,20 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
|
||||
|
namespace Volo.Abp.MultiLingualObject.TestObjects |
||||
|
{ |
||||
|
public class MultiLingualBook : IHasMultiLingual<MultiLingualBookTranslation> |
||||
|
{ |
||||
|
public MultiLingualBook(Guid id, decimal price) |
||||
|
{ |
||||
|
Id = id; |
||||
|
Price = price; |
||||
|
} |
||||
|
|
||||
|
public Guid Id { get; } |
||||
|
|
||||
|
public decimal Price { get; set; } |
||||
|
|
||||
|
public ICollection<MultiLingualBookTranslation> Translations { get; set; } |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,13 @@ |
|||||
|
using System; |
||||
|
|
||||
|
namespace Volo.Abp.MultiLingualObject.TestObjects |
||||
|
{ |
||||
|
public class MultiLingualBookDto |
||||
|
{ |
||||
|
public Guid Id { get; set; } |
||||
|
|
||||
|
public string Name { get; set; } |
||||
|
|
||||
|
public decimal Price { get; set; } |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,11 @@ |
|||||
|
using System; |
||||
|
|
||||
|
namespace Volo.Abp.MultiLingualObject.TestObjects |
||||
|
{ |
||||
|
public class MultiLingualBookTranslation : IMultiLingualTranslation |
||||
|
{ |
||||
|
public string Name { get; set; } |
||||
|
|
||||
|
public string Language { get; set; } |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue