Browse Source

Create MultiLingualObjectManager

pull/5774/head
liangshiwei 6 years ago
parent
commit
83d5b754bb
  1. 41
      framework/src/Volo.Abp.AutoMapper/AutoMapper/AbpAutoMapperMultiLingualDtoExtensions.cs
  2. 2
      framework/src/Volo.Abp.AutoMapper/Volo.Abp.AutoMapper.csproj
  3. 4
      framework/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AbpAutoMapperModule.cs
  4. 12
      framework/src/Volo.Abp.MultiLingualObject/Volo/Abp/MultiLingualObject/IMultiLingualObjectManager.cs
  5. 41
      framework/src/Volo.Abp.MultiLingualObject/Volo/Abp/MultiLingualObject/MultiLingualObjectManager.cs
  6. 107
      framework/test/Volo.Abp.AutoMapper.Tests/AutoMapper/AbpAutoMapperMultiLingualDtoExtensions_Tests.cs
  7. 132
      framework/test/Volo.Abp.AutoMapper.Tests/AutoMapper/AbpAutoMapperMultiLingualDto_Tests.cs
  8. 14
      framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/AutoMapperTestModule.cs
  9. 91
      framework/test/Volo.Abp.MultiLingualObject.Tests/Volo/Abp/MultiLingualObject/MultiLingualObject_Tests.cs

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

@ -1,41 +0,0 @@
using Volo.Abp.MultiLingualObject;
using Volo.Abp.Settings;
namespace AutoMapper
{
public static class AbpAutoMapperMultiLingualDtoExtensions
{
public static CreateMultiLingualMapResult<TSource, TTranslation, TDestination> MapMultiLingual<TSource,
TTranslation, TDestination>(
this IMappingExpression<TSource, TDestination> mappingExpression,
Profile profile,
ISettingProvider provider,
bool fallbackToParentCultures = false)
where TDestination : class
where TSource : IHasMultiLingual<TTranslation>
where TTranslation : class, IMultiLingualTranslation
{
return new CreateMultiLingualMapResult<TSource, TTranslation, TDestination>
{
TranslationMap = profile.CreateMap<TTranslation, TDestination>(),
EntityMap = mappingExpression.BeforeMap((source, destination, context) =>
{
var translation = source.GetMultiLingualTranslation(provider, fallbackToParentCultures);
if (translation != null)
{
context.Mapper.Map(translation, destination);
}
})
};
}
}
public class CreateMultiLingualMapResult<TMultiLingual, TTranslation, TDestination>
{
public IMappingExpression<TTranslation, TDestination> TranslationMap { get; set; }
public IMappingExpression<TMultiLingual, TDestination> EntityMap { get; set; }
}
}

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

@ -16,10 +16,8 @@
<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" />
</ItemGroup>
<ItemGroup>

4
framework/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AbpAutoMapperModule.cs

@ -4,7 +4,6 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Volo.Abp.Auditing;
using Volo.Abp.Modularity;
using Volo.Abp.MultiLingualObject;
using Volo.Abp.ObjectExtending;
using Volo.Abp.ObjectMapping;
@ -13,8 +12,7 @@ namespace Volo.Abp.AutoMapper
[DependsOn(
typeof(AbpObjectMappingModule),
typeof(AbpObjectExtendingModule),
typeof(AbpAuditingModule),
typeof(AbpMultiLingualObjectModule)
typeof(AbpAuditingModule)
)]
public class AbpAutoMapperModule : AbpModule
{

12
framework/src/Volo.Abp.MultiLingualObject/Volo/Abp/MultiLingualObject/IMultiLingualObjectManager.cs

@ -0,0 +1,12 @@
using System.Threading.Tasks;
namespace Volo.Abp.MultiLingualObject
{
public interface IMultiLingualObjectManager
{
Task<TTranslation> GetTranslationAsync<TMultiLingual, TTranslation>(TMultiLingual multiLingual,
bool fallbackToParentCultures = true, string culture = null)
where TMultiLingual : IHasMultiLingual<TTranslation>
where TTranslation : class, IMultiLingualTranslation;
}
}

41
framework/src/Volo.Abp.MultiLingualObject/Volo/Abp/MultiLingualObject/MultiLingualObjectExtensions.cs → framework/src/Volo.Abp.MultiLingualObject/Volo/Abp/MultiLingualObject/MultiLingualObjectManager.cs

@ -2,27 +2,39 @@
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 static class MultiLingualObjectExtensions
public class MultiLingualObjectManager : IMultiLingualObjectManager, ITransientDependency
{
public static TTranslation GetMultiLingualTranslation<TTranslation>(
this IHasMultiLingual<TTranslation> hasMultiLingual,
ISettingProvider settingProvider,
bool fallbackToParentCultures = false)
protected ISettingProvider SettingProvider { get; }
protected const int MaxCultureFallbackDepth = 5;
public MultiLingualObjectManager(ISettingProvider settingProvider)
{
SettingProvider = settingProvider;
}
public virtual async Task<TTranslation> GetTranslationAsync<TMultiLingual, TTranslation>(TMultiLingual multiLingual,
bool fallbackToParentCultures = true,
string culture = null)
where TMultiLingual : IHasMultiLingual<TTranslation>
where TTranslation : class, IMultiLingualTranslation
{
if (hasMultiLingual.Translations == null || !hasMultiLingual.Translations.Any())
culture ??= CultureInfo.CurrentUICulture.Name;
if (multiLingual.Translations == null || !multiLingual.Translations.Any())
{
return null;
}
var translation =
hasMultiLingual.Translations.FirstOrDefault(pt => pt.Language == CultureInfo.CurrentUICulture.Name);
multiLingual.Translations.FirstOrDefault(pt => pt.Language == culture);
if (translation != null)
{
return translation;
@ -32,29 +44,26 @@ namespace Volo.Abp.MultiLingualObject
{
translation =
GeTranslationBasedOnCulturalRecursive(
CultureInfo.CurrentUICulture.Parent, hasMultiLingual.Translations, 0);
CultureInfo.CurrentUICulture.Parent, multiLingual.Translations, 0);
if (translation != null)
{
return translation;
}
}
var defaultLanguage = AsyncHelper.RunSync(() =>
settingProvider.GetOrNullAsync(LocalizationSettingNames.DefaultLanguage));
var defaultLanguage = await SettingProvider.GetOrNullAsync(LocalizationSettingNames.DefaultLanguage);
translation = hasMultiLingual.Translations.FirstOrDefault(pt => pt.Language == defaultLanguage);
translation = multiLingual.Translations.FirstOrDefault(pt => pt.Language == defaultLanguage);
if (translation != null)
{
return translation;
}
translation = hasMultiLingual.Translations.FirstOrDefault();
translation = multiLingual.Translations.FirstOrDefault();
return translation;
}
private const int MaxCultureFallbackDepth = 5;
private static TTranslation GeTranslationBasedOnCulturalRecursive<TTranslation>(
protected virtual TTranslation GeTranslationBasedOnCulturalRecursive<TTranslation>(
CultureInfo culture, ICollection<TTranslation> translations, int currentDepth)
where TTranslation : class, IMultiLingualTranslation
{

107
framework/test/Volo.Abp.AutoMapper.Tests/AutoMapper/AbpAutoMapperMultiLingualDtoExtensions_Tests.cs

@ -1,107 +0,0 @@
using System;
using System.Collections.Generic;
using Microsoft.Extensions.DependencyInjection;
using Shouldly;
using Volo.Abp;
using Volo.Abp.AutoMapper;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Localization;
using Volo.Abp.MultiLingualObject.TestObjects;
using Volo.Abp.Settings;
using Volo.Abp.Testing;
using Xunit;
namespace AutoMapper
{
public class AbpAutoMapperMultiLingualDtoExtensions_Tests : AbpIntegratedTest<AutoMapperTestModule>
{
private readonly Volo.Abp.ObjectMapping.IObjectMapper _objectMapper;
private readonly MultiLingualBook _book;
public AbpAutoMapperMultiLingualDtoExtensions_Tests()
{
_objectMapper = ServiceProvider.GetRequiredService<Volo.Abp.ObjectMapping.IObjectMapper>();
var id = Guid.NewGuid();
_book = new MultiLingualBook(id, 100)
{
Translations = new List<MultiLingualBookTranslation>
{
new MultiLingualBookTranslation
{
CoreId = id,
Language = "en",
Name = "C# in Depth"
},
new MultiLingualBookTranslation
{
CoreId = id,
Language = "zh-Hans",
Name = "深入理解C#"
}
}
};
}
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);
}
}
}
public class BookProfile : Profile, ITransientDependency
{
public BookProfile()
{
}
public BookProfile(ISettingProvider settingProvider)
{
CreateMap<MultiLingualBook, MultiLingualBookDto>()
.MapMultiLingual<MultiLingualBook, MultiLingualBookTranslation, MultiLingualBookDto>(this,
settingProvider, true)
.TranslationMap
.ForMember(d => d.Id, m => m.MapFrom(s => s.CoreId));
;
}
}
}

132
framework/test/Volo.Abp.AutoMapper.Tests/AutoMapper/AbpAutoMapperMultiLingualDto_Tests.cs

@ -0,0 +1,132 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Shouldly;
using Volo.Abp;
using Volo.Abp.AutoMapper;
using Volo.Abp.Localization;
using Volo.Abp.MultiLingualObject;
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 IMultiLingualObjectManager _multiLingualObjectManager;
private readonly MultiLingualBook _book;
public AbpAutoMapperMultiLingualDto_Tests()
{
_multiLingualObjectManager = ServiceProvider.GetRequiredService<IMultiLingualObjectManager>();
_objectMapper = ServiceProvider.GetRequiredService<Volo.Abp.ObjectMapping.IObjectMapper>();
var id = Guid.NewGuid();
_book = new MultiLingualBook(id, 100)
{
Translations = new List<MultiLingualBookTranslation>()
};
var en = new MultiLingualBookTranslation
{
CoreId = id,
Language = "en",
Name = "C# in Depth",
Core = _book
};
var zh = new MultiLingualBookTranslation
{
CoreId = id,
Language = "zh-Hans",
Name = "深入理解C#",
Core = _book
};
_book.Translations.Add(en);
_book.Translations.Add(zh);
}
protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options)
{
options.UseAutofac();
}
[Fact]
public async Task Should_Map_Current_UI_Culture()
{
using (CultureHelper.Use("zh-Hans"))
{
var translation =
await _multiLingualObjectManager
.GetTranslationAsync<MultiLingualBook, MultiLingualBookTranslation>(_book);
var bookDto = _objectMapper.Map<MultiLingualBookTranslation, MultiLingualBookDto>(translation);
bookDto.Name.ShouldBe("深入理解C#");
bookDto.Price.ShouldBe(_book.Price);
bookDto.Id.ShouldBe(_book.Id);
}
}
[Fact]
public async Task Should_Map_Fallback_UI_Culture()
{
using (CultureHelper.Use("en-us"))
{
var translation =
await _multiLingualObjectManager
.GetTranslationAsync<MultiLingualBook, MultiLingualBookTranslation>(_book);
var bookDto = _objectMapper.Map<MultiLingualBookTranslation, MultiLingualBookDto>(translation);
bookDto.Name.ShouldBe("C# in Depth");
bookDto.Price.ShouldBe(_book.Price);
bookDto.Id.ShouldBe(_book.Id);
}
}
[Fact]
public async Task Should_Map_Default_Language()
{
using (CultureHelper.Use("tr"))
{
var translation =
await _multiLingualObjectManager
.GetTranslationAsync<MultiLingualBook, MultiLingualBookTranslation>(_book);
var bookDto = _objectMapper.Map<MultiLingualBookTranslation, MultiLingualBookDto>(translation);
bookDto.Name.ShouldBe("C# in Depth");
bookDto.Price.ShouldBe(_book.Price);
bookDto.Id.ShouldBe(_book.Id);
}
}
[Fact]
public async Task Should_Map_Specified_Language()
{
using (CultureHelper.Use("zh-Hans"))
{
var translation = await _multiLingualObjectManager.GetTranslationAsync<MultiLingualBook, MultiLingualBookTranslation>(_book, culture:"en");
var bookDto = _objectMapper.Map<MultiLingualBookTranslation,MultiLingualBookDto>(translation);
bookDto.Name.ShouldBe("C# in Depth");
bookDto.Price.ShouldBe(_book.Price);
bookDto.Id.ShouldBe(_book.Id);
}
}
}
public class BookProfile : Profile
{
public BookProfile()
{
CreateMap<MultiLingualBookTranslation, MultiLingualBookDto>()
.ForMember(d => d.Price, m => m.MapFrom(s => s.Core.Price))
.ForMember(d => d.Id, m => m.MapFrom(s => s.CoreId));
}
}
}

14
framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/AutoMapperTestModule.cs

@ -1,13 +1,13 @@
using AutoMapper;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Modularity;
using Volo.Abp.Modularity;
using Volo.Abp.MultiLingualObject;
using Volo.Abp.ObjectExtending;
namespace Volo.Abp.AutoMapper
{
[DependsOn(
typeof(AbpAutoMapperModule),
typeof(AbpObjectExtendingTestModule)
typeof(AbpObjectExtendingTestModule),
typeof(AbpMultiLingualObjectModule)
)]
public class AutoMapperTestModule : AbpModule
{
@ -16,12 +16,6 @@ namespace Volo.Abp.AutoMapper
Configure<AbpAutoMapperOptions>(options =>
{
options.AddMaps<AutoMapperTestModule>();
options.Configurators.Add(configurationContext =>
{
configurationContext.MapperConfiguration.AddProfile(configurationContext.ServiceProvider
.GetService<BookProfile>());
});
});
}
}

91
framework/test/Volo.Abp.MultiLingualObject.Tests/Volo/Abp/MultiLingualObject/MultiLingualObject_Tests.cs

@ -1,12 +1,12 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
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.Settings;
using Volo.Abp.Testing;
using Xunit;
@ -14,32 +14,38 @@ namespace Volo.Abp.MultiLingualObject
{
public class MultiLingualObject_Tests : AbpIntegratedTest<AbpMultiLingualObjectTestModule>
{
private readonly IObjectMapper<MultiLingualBook, MultiLingualBookDto> _objectMapper;
private readonly IObjectMapper _objectMapper;
private readonly IMultiLingualObjectManager _multiLingualObjectManager;
private readonly MultiLingualBook _book;
public MultiLingualObject_Tests()
{
_objectMapper = ServiceProvider.GetRequiredService<IObjectMapper<MultiLingualBook, MultiLingualBookDto>>();
_objectMapper = ServiceProvider.GetRequiredService<IObjectMapper>();
_multiLingualObjectManager = ServiceProvider.GetRequiredService<IMultiLingualObjectManager>();
var id = Guid.NewGuid();
_book = new MultiLingualBook(id, 100)
{
Translations = new List<MultiLingualBookTranslation>
{
new MultiLingualBookTranslation
{
CoreId = id,
Language = "en",
Name = "C# in Depth"
},
new MultiLingualBookTranslation
{
CoreId = id,
Language = "zh-Hans",
Name = "深入理解C#"
}
}
Translations = new List<MultiLingualBookTranslation>()
};
var en = new MultiLingualBookTranslation
{
CoreId = id,
Language = "en",
Name = "C# in Depth",
Core = _book
};
var zh = new MultiLingualBookTranslation
{
CoreId = id,
Language = "zh-Hans",
Name = "深入理解C#",
Core = _book
};
_book.Translations.Add(en);
_book.Translations.Add(zh);
}
protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options)
@ -48,11 +54,12 @@ namespace Volo.Abp.MultiLingualObject
}
[Fact]
public void Should_Map_Current_UI_Culture()
public async Task Should_Map_Current_UI_Culture()
{
using (CultureHelper.Use("zh-Hans"))
{
var bookDto = _objectMapper.Map(_book);
var translation = await _multiLingualObjectManager.GetTranslationAsync<MultiLingualBook, MultiLingualBookTranslation>(_book);
var bookDto = _objectMapper.Map<MultiLingualBookTranslation,MultiLingualBookDto>(translation);
bookDto.Name.ShouldBe("深入理解C#");
bookDto.Price.ShouldBe(_book.Price);
@ -61,11 +68,12 @@ namespace Volo.Abp.MultiLingualObject
}
[Fact]
public void Should_Map_Fallback_UI_Culture()
public async Task Should_Map_Fallback_UI_Culture()
{
using (CultureHelper.Use("en-us"))
{
var bookDto = _objectMapper.Map(_book);
var translation = await _multiLingualObjectManager.GetTranslationAsync<MultiLingualBook, MultiLingualBookTranslation>(_book);
var bookDto = _objectMapper.Map<MultiLingualBookTranslation,MultiLingualBookDto>(translation);
bookDto.Name.ShouldBe("C# in Depth");
bookDto.Price.ShouldBe(_book.Price);
@ -74,11 +82,26 @@ namespace Volo.Abp.MultiLingualObject
}
[Fact]
public void Should_Map_Default_Language()
public async Task Should_Map_Default_Language()
{
using (CultureHelper.Use("tr"))
{
var bookDto = _objectMapper.Map(_book);
var translation = await _multiLingualObjectManager.GetTranslationAsync<MultiLingualBook, MultiLingualBookTranslation>(_book);
var bookDto = _objectMapper.Map<MultiLingualBookTranslation,MultiLingualBookDto>(translation);
bookDto.Name.ShouldBe("C# in Depth");
bookDto.Price.ShouldBe(_book.Price);
bookDto.Id.ShouldBe(_book.Id);
}
}
[Fact]
public async Task Should_Map_Specified_Language()
{
using (CultureHelper.Use("zh-Hans"))
{
var translation = await _multiLingualObjectManager.GetTranslationAsync<MultiLingualBook, MultiLingualBookTranslation>(_book, culture:"en");
var bookDto = _objectMapper.Map<MultiLingualBookTranslation,MultiLingualBookDto>(translation);
bookDto.Name.ShouldBe("C# in Depth");
bookDto.Price.ShouldBe(_book.Price);
@ -87,29 +110,21 @@ namespace Volo.Abp.MultiLingualObject
}
}
public class MultiLingualBookObjectMapper : IObjectMapper<MultiLingualBook, MultiLingualBookDto>,
public class MultiLingualBookObjectMapper : IObjectMapper<MultiLingualBookTranslation, MultiLingualBookDto>,
ITransientDependency
{
private readonly ISettingProvider _settingProvider;
public MultiLingualBookObjectMapper(ISettingProvider settingProvider)
public MultiLingualBookDto Map(MultiLingualBookTranslation source)
{
_settingProvider = settingProvider;
}
public MultiLingualBookDto Map(MultiLingualBook source)
{
var translation = source.GetMultiLingualTranslation(_settingProvider, true);
return new MultiLingualBookDto
{
Id = source.Id,
Name = translation.Name,
Price = source.Price
Price = source.Core.Price,
Id = source.CoreId,
Name = source.Name
};
}
public MultiLingualBookDto Map(MultiLingualBook source, MultiLingualBookDto destination)
public MultiLingualBookDto Map(MultiLingualBookTranslation source, MultiLingualBookDto destination)
{
return default;
}

Loading…
Cancel
Save