Browse Source

Merge pull request #1145 from colinin/localization-external-store

feat(localization): Implement multi-language external store
pull/1149/head
yx lin 11 months ago
committed by GitHub
parent
commit
17c028cd3c
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 7
      aspnet-core/LINGYUN.MicroService.SingleProject.sln
  2. 3
      aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.IP.Location/LINGYUN.Abp.AuditLogging.IP.Location.csproj
  3. 4
      aspnet-core/framework/localization/LINGYUN.Abp.AspNetCore.Mvc.Localization/LINGYUN/Abp/AspNetCore/Mvc/Localization/TextAppService.cs
  4. 40
      aspnet-core/modules/localization-management/LINGYUN.Abp.LocalizationManagement.Application.Contracts/LINGYUN/Abp/LocalizationManagement/Permissions/LocalizationManagementPermissionDefinitionProvider.cs
  5. 5
      aspnet-core/modules/localization-management/LINGYUN.Abp.LocalizationManagement.Application/LINGYUN/Abp/LocalizationManagement/LanguageAppService.cs
  6. 5
      aspnet-core/modules/localization-management/LINGYUN.Abp.LocalizationManagement.Application/LINGYUN/Abp/LocalizationManagement/ResourceAppService.cs
  7. 5
      aspnet-core/modules/localization-management/LINGYUN.Abp.LocalizationManagement.Application/LINGYUN/Abp/LocalizationManagement/TextAppService.cs
  8. 1
      aspnet-core/modules/localization-management/LINGYUN.Abp.LocalizationManagement.Domain.Shared/LINGYUN.Abp.LocalizationManagement.Domain.Shared.csproj
  9. 2
      aspnet-core/modules/localization-management/LINGYUN.Abp.LocalizationManagement.Domain.Shared/LINGYUN/Abp/LocalizationManagement/AbpLocalizationManagementDomainSharedModule.cs
  10. 25
      aspnet-core/modules/localization-management/LINGYUN.Abp.LocalizationManagement.Domain.Shared/LINGYUN/Abp/LocalizationManagement/Features/LocalizationManagementFeatureDefinitionProvider.cs
  11. 8
      aspnet-core/modules/localization-management/LINGYUN.Abp.LocalizationManagement.Domain.Shared/LINGYUN/Abp/LocalizationManagement/Features/LocalizationManagementFeatures.cs
  12. 3
      aspnet-core/modules/localization-management/LINGYUN.Abp.LocalizationManagement.Domain.Shared/LINGYUN/Abp/LocalizationManagement/Localization/Resources/en.json
  13. 3
      aspnet-core/modules/localization-management/LINGYUN.Abp.LocalizationManagement.Domain.Shared/LINGYUN/Abp/LocalizationManagement/Localization/Resources/zh-Hans.json
  14. 69
      aspnet-core/modules/localization-management/LINGYUN.Abp.LocalizationManagement.Domain/LINGYUN/Abp/LocalizationManagement/External/ExternalLocalizationResourceContributor.cs
  15. 90
      aspnet-core/modules/localization-management/LINGYUN.Abp.LocalizationManagement.Domain/LINGYUN/Abp/LocalizationManagement/External/ExternalLocalizationStore.cs
  16. 146
      aspnet-core/modules/localization-management/LINGYUN.Abp.LocalizationManagement.Domain/LINGYUN/Abp/LocalizationManagement/External/ExternalLocalizationStoreCache.cs
  17. 29
      aspnet-core/modules/localization-management/LINGYUN.Abp.LocalizationManagement.Domain/LINGYUN/Abp/LocalizationManagement/External/ExternalLocalizationTextCacheItem.cs
  18. 29
      aspnet-core/modules/localization-management/LINGYUN.Abp.LocalizationManagement.Domain/LINGYUN/Abp/LocalizationManagement/External/ExternalLocalizationTextStampCacheItem.cs
  19. 143
      aspnet-core/modules/localization-management/LINGYUN.Abp.LocalizationManagement.Domain/LINGYUN/Abp/LocalizationManagement/External/ExternalLocalizationTextStoreCache.cs
  20. 16
      aspnet-core/modules/localization-management/LINGYUN.Abp.LocalizationManagement.Domain/LINGYUN/Abp/LocalizationManagement/External/IExternalLocalizationStoreCache.cs
  21. 14
      aspnet-core/modules/localization-management/LINGYUN.Abp.LocalizationManagement.Domain/LINGYUN/Abp/LocalizationManagement/External/IExternalLocalizationTextStoreCache.cs
  22. 36
      aspnet-core/modules/localization-management/LINGYUN.Abp.LocalizationManagement.Domain/LINGYUN/Abp/LocalizationManagement/External/LocalizationResourceCacheInvalidator.cs
  23. 32
      aspnet-core/modules/localization-management/LINGYUN.Abp.LocalizationManagement.Domain/LINGYUN/Abp/LocalizationManagement/External/LocalizationResourceCacheItem.cs
  24. 30
      aspnet-core/modules/localization-management/LINGYUN.Abp.LocalizationManagement.Domain/LINGYUN/Abp/LocalizationManagement/External/LocalizationResourcesCacheItem.cs
  25. 31
      aspnet-core/modules/localization-management/LINGYUN.Abp.LocalizationManagement.Domain/LINGYUN/Abp/LocalizationManagement/External/LocalizationTextMemoryCacheItem.cs
  26. 2
      aspnet-core/modules/localization-management/LINGYUN.Abp.LocalizationManagement.Domain/LINGYUN/Abp/LocalizationManagement/IResourceRepository.cs
  27. 4
      aspnet-core/modules/localization-management/LINGYUN.Abp.LocalizationManagement.Domain/LINGYUN/Abp/LocalizationManagement/LocalizationLanguageCacheItem.cs
  28. 11
      aspnet-core/modules/localization-management/LINGYUN.Abp.LocalizationManagement.Domain/LINGYUN/Abp/LocalizationManagement/LocalizationTextCacheInvalidator.cs
  29. 2
      aspnet-core/modules/localization-management/LINGYUN.Abp.LocalizationManagement.Domain/LINGYUN/Abp/LocalizationManagement/LocalizationTextCacheItem.cs
  30. 10
      aspnet-core/modules/localization-management/LINGYUN.Abp.LocalizationManagement.EntityFrameworkCore/LINGYUN/Abp/LocalizationManagement/EntityFrameworkCore/EfCoreResourceRepository.cs

7
aspnet-core/LINGYUN.MicroService.SingleProject.sln

@ -664,6 +664,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.Identity.AspNet
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.WeChat.Work.AspNetCore", "framework\wechat\LINGYUN.Abp.WeChat.Work.AspNetCore\LINGYUN.Abp.WeChat.Work.AspNetCore.csproj", "{40DC9A79-2E8A-4C6F-A637-5C09D6F26B0E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.Identity.WeChat.Work", "framework\wechat\LINGYUN.Abp.Identity.WeChat.Work\LINGYUN.Abp.Identity.WeChat.Work.csproj", "{CCC8A29C-1FC1-044F-895A-EC6894CDC8E5}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -1762,6 +1764,10 @@ Global
{40DC9A79-2E8A-4C6F-A637-5C09D6F26B0E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{40DC9A79-2E8A-4C6F-A637-5C09D6F26B0E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{40DC9A79-2E8A-4C6F-A637-5C09D6F26B0E}.Release|Any CPU.Build.0 = Release|Any CPU
{CCC8A29C-1FC1-044F-895A-EC6894CDC8E5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CCC8A29C-1FC1-044F-895A-EC6894CDC8E5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CCC8A29C-1FC1-044F-895A-EC6894CDC8E5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CCC8A29C-1FC1-044F-895A-EC6894CDC8E5}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -2085,6 +2091,7 @@ Global
{4C7594CE-FB2F-4309-B95C-D4460892CF6E} = {7C714185-D3D9-4D94-B5CB-D857A0091F04}
{C9266D5D-3860-09C3-F566-489BBB57A534} = {D94D6AFE-20BD-4F21-8708-03F5E34F49FC}
{40DC9A79-2E8A-4C6F-A637-5C09D6F26B0E} = {91867618-0D86-4410-91C6-B1166A9ACDF9}
{CCC8A29C-1FC1-044F-895A-EC6894CDC8E5} = {91867618-0D86-4410-91C6-B1166A9ACDF9}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {711A43C0-A2F8-4E5C-9B9F-F2551E4B3FF1}

3
aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.IP.Location/LINGYUN.Abp.AuditLogging.IP.Location.csproj

@ -14,9 +14,6 @@
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
<RootNamespace />
</PropertyGroup>
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\common\LINGYUN.Abp.IP.Location\LINGYUN.Abp.IP.Location.csproj" />

4
aspnet-core/framework/localization/LINGYUN.Abp.AspNetCore.Mvc.Localization/LINGYUN/Abp/AspNetCore/Mvc/Localization/TextAppService.cs

@ -99,7 +99,7 @@ public class TextAppService : ApplicationService, ITextAppService
using (CultureHelper.Use(cultureName, cultureName))
{
localizedStrings = (await localizer.GetAllStringsAsync(true))
localizedStrings = (await localizer.GetAllStringsAsync(true, false, true))
.WhereIf(!filter.IsNullOrWhiteSpace(), x => x.Name.Contains(filter))
.OrderBy(l => l.Name);
}
@ -112,7 +112,7 @@ public class TextAppService : ApplicationService, ITextAppService
{
using (CultureHelper.Use(targetCultureName, targetCultureName))
{
targetLocalizedStrings = (await localizer.GetAllStringsAsync(true))
targetLocalizedStrings = (await localizer.GetAllStringsAsync(false, false, true))
.WhereIf(!filter.IsNullOrWhiteSpace(), x => x.Name.Contains(filter))
.OrderBy(l => l.Name);
}

40
aspnet-core/modules/localization-management/LINGYUN.Abp.LocalizationManagement.Application.Contracts/LINGYUN/Abp/LocalizationManagement/Permissions/LocalizationManagementPermissionDefinitionProvider.cs

@ -1,5 +1,7 @@
using LINGYUN.Abp.LocalizationManagement.Localization;
using LINGYUN.Abp.LocalizationManagement.Features;
using LINGYUN.Abp.LocalizationManagement.Localization;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Features;
using Volo.Abp.Localization;
namespace LINGYUN.Abp.LocalizationManagement.Permissions;
@ -15,53 +17,65 @@ public class LocalizationManagementPermissionDefinitionProvider : PermissionDefi
var resourcePermission = permissionGroup.AddPermission(
LocalizationManagementPermissions.Resource.Default,
L("Permissions:Resource"),
Volo.Abp.MultiTenancy.MultiTenancySides.Host);
Volo.Abp.MultiTenancy.MultiTenancySides.Host)
.RequireFeatures(LocalizationManagementFeatures.Enable);
resourcePermission.AddChild(
LocalizationManagementPermissions.Resource.Create,
L("Permissions:Create"),
Volo.Abp.MultiTenancy.MultiTenancySides.Host);
Volo.Abp.MultiTenancy.MultiTenancySides.Host)
.RequireFeatures(LocalizationManagementFeatures.Enable);
resourcePermission.AddChild(
LocalizationManagementPermissions.Resource.Update,
L("Permissions:Update"),
Volo.Abp.MultiTenancy.MultiTenancySides.Host);
Volo.Abp.MultiTenancy.MultiTenancySides.Host)
.RequireFeatures(LocalizationManagementFeatures.Enable);
resourcePermission.AddChild(
LocalizationManagementPermissions.Resource.Delete,
L("Permissions:Delete"),
Volo.Abp.MultiTenancy.MultiTenancySides.Host);
Volo.Abp.MultiTenancy.MultiTenancySides.Host)
.RequireFeatures(LocalizationManagementFeatures.Enable);
var languagePermission = permissionGroup.AddPermission(
LocalizationManagementPermissions.Language.Default,
L("Permissions:Language"),
Volo.Abp.MultiTenancy.MultiTenancySides.Host);
Volo.Abp.MultiTenancy.MultiTenancySides.Host)
.RequireFeatures(LocalizationManagementFeatures.Enable);
languagePermission.AddChild(
LocalizationManagementPermissions.Language.Create,
L("Permissions:Create"),
Volo.Abp.MultiTenancy.MultiTenancySides.Host);
Volo.Abp.MultiTenancy.MultiTenancySides.Host)
.RequireFeatures(LocalizationManagementFeatures.Enable);
languagePermission.AddChild(
LocalizationManagementPermissions.Language.Update,
L("Permissions:Update"),
Volo.Abp.MultiTenancy.MultiTenancySides.Host);
Volo.Abp.MultiTenancy.MultiTenancySides.Host)
.RequireFeatures(LocalizationManagementFeatures.Enable);
languagePermission.AddChild(
LocalizationManagementPermissions.Language.Delete,
L("Permissions:Delete"),
Volo.Abp.MultiTenancy.MultiTenancySides.Host);
Volo.Abp.MultiTenancy.MultiTenancySides.Host)
.RequireFeatures(LocalizationManagementFeatures.Enable);
var textPermission = permissionGroup.AddPermission(
LocalizationManagementPermissions.Text.Default,
L("Permissions:Text"),
Volo.Abp.MultiTenancy.MultiTenancySides.Host);
Volo.Abp.MultiTenancy.MultiTenancySides.Host)
.RequireFeatures(LocalizationManagementFeatures.Enable);
textPermission.AddChild(
LocalizationManagementPermissions.Text.Create,
L("Permissions:Create"),
Volo.Abp.MultiTenancy.MultiTenancySides.Host);
Volo.Abp.MultiTenancy.MultiTenancySides.Host)
.RequireFeatures(LocalizationManagementFeatures.Enable);
textPermission.AddChild(
LocalizationManagementPermissions.Text.Update,
L("Permissions:Update"),
Volo.Abp.MultiTenancy.MultiTenancySides.Host);
Volo.Abp.MultiTenancy.MultiTenancySides.Host)
.RequireFeatures(LocalizationManagementFeatures.Enable);
textPermission.AddChild(
LocalizationManagementPermissions.Text.Delete,
L("Permissions:Delete"),
Volo.Abp.MultiTenancy.MultiTenancySides.Host);
Volo.Abp.MultiTenancy.MultiTenancySides.Host)
.RequireFeatures(LocalizationManagementFeatures.Enable);
}
private static LocalizableString L(string name)

5
aspnet-core/modules/localization-management/LINGYUN.Abp.LocalizationManagement.Application/LINGYUN/Abp/LocalizationManagement/LanguageAppService.cs

@ -1,6 +1,8 @@
using LINGYUN.Abp.LocalizationManagement.Permissions;
using LINGYUN.Abp.LocalizationManagement.Features;
using LINGYUN.Abp.LocalizationManagement.Permissions;
using Microsoft.AspNetCore.Authorization;
using System.Globalization;
using System.Runtime.Versioning;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Localization;
@ -8,6 +10,7 @@ using Volo.Abp.Localization;
namespace LINGYUN.Abp.LocalizationManagement;
[Authorize(LocalizationManagementPermissions.Language.Default)]
[RequiresPreviewFeatures(LocalizationManagementFeatures.Enable)]
public class LanguageAppService : LocalizationAppServiceBase, ILanguageAppService
{
private readonly ILanguageRepository _repository;

5
aspnet-core/modules/localization-management/LINGYUN.Abp.LocalizationManagement.Application/LINGYUN/Abp/LocalizationManagement/ResourceAppService.cs

@ -1,11 +1,14 @@
using LINGYUN.Abp.LocalizationManagement.Permissions;
using LINGYUN.Abp.LocalizationManagement.Features;
using LINGYUN.Abp.LocalizationManagement.Permissions;
using Microsoft.AspNetCore.Authorization;
using System.Runtime.Versioning;
using System.Threading.Tasks;
using Volo.Abp;
namespace LINGYUN.Abp.LocalizationManagement;
[Authorize(LocalizationManagementPermissions.Resource.Default)]
[RequiresPreviewFeatures(LocalizationManagementFeatures.Enable)]
public class ResourceAppService : LocalizationAppServiceBase, IResourceAppService
{
private readonly IResourceRepository _repository;

5
aspnet-core/modules/localization-management/LINGYUN.Abp.LocalizationManagement.Application/LINGYUN/Abp/LocalizationManagement/TextAppService.cs

@ -1,10 +1,13 @@
using LINGYUN.Abp.LocalizationManagement.Permissions;
using LINGYUN.Abp.LocalizationManagement.Features;
using LINGYUN.Abp.LocalizationManagement.Permissions;
using Microsoft.AspNetCore.Authorization;
using System.Runtime.Versioning;
using System.Threading.Tasks;
namespace LINGYUN.Abp.LocalizationManagement;
[Authorize(LocalizationManagementPermissions.Text.Default)]
[RequiresPreviewFeatures(LocalizationManagementFeatures.Enable)]
public class TextAppService : LocalizationAppServiceBase, ITextAppService
{
private readonly ITextRepository _textRepository;

1
aspnet-core/modules/localization-management/LINGYUN.Abp.LocalizationManagement.Domain.Shared/LINGYUN.Abp.LocalizationManagement.Domain.Shared.csproj

@ -24,6 +24,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.Features" />
<PackageReference Include="Volo.Abp.Validation" />
<PackageReference Include="Volo.Abp.Localization" />
</ItemGroup>

2
aspnet-core/modules/localization-management/LINGYUN.Abp.LocalizationManagement.Domain.Shared/LINGYUN/Abp/LocalizationManagement/AbpLocalizationManagementDomainSharedModule.cs

@ -1,4 +1,5 @@
using LINGYUN.Abp.LocalizationManagement.Localization;
using Volo.Abp.Features;
using Volo.Abp.Localization;
using Volo.Abp.Localization.ExceptionHandling;
using Volo.Abp.Modularity;
@ -8,6 +9,7 @@ using Volo.Abp.VirtualFileSystem;
namespace LINGYUN.Abp.LocalizationManagement;
[DependsOn(
typeof(AbpFeaturesModule),
typeof(AbpValidationModule),
typeof(AbpLocalizationModule))]
public class AbpLocalizationManagementDomainSharedModule : AbpModule

25
aspnet-core/modules/localization-management/LINGYUN.Abp.LocalizationManagement.Domain.Shared/LINGYUN/Abp/LocalizationManagement/Features/LocalizationManagementFeatureDefinitionProvider.cs

@ -0,0 +1,25 @@
using LINGYUN.Abp.LocalizationManagement.Localization;
using Volo.Abp.Features;
using Volo.Abp.Localization;
using Volo.Abp.Validation.StringValues;
namespace LINGYUN.Abp.LocalizationManagement.Features;
public class LocalizationManagementFeatureDefinitionProvider : FeatureDefinitionProvider
{
public override void Define(IFeatureDefinitionContext context)
{
var group = context.AddGroup(LocalizationManagementFeatures.GroupName,
L("Feature:LocalizationManagement"));
group.AddFeature(LocalizationManagementFeatures.Enable,
"true",
L("Feature:LocalizationManagementEnable"),
L("Feature:LocalizationManagementEnableDesc"),
new ToggleStringValueType());
}
private static LocalizableString L(string name)
{
return LocalizableString.Create<LocalizationManagementResource>(name);
}
}

8
aspnet-core/modules/localization-management/LINGYUN.Abp.LocalizationManagement.Domain.Shared/LINGYUN/Abp/LocalizationManagement/Features/LocalizationManagementFeatures.cs

@ -0,0 +1,8 @@
namespace LINGYUN.Abp.LocalizationManagement.Features;
public static class LocalizationManagementFeatures
{
public const string GroupName = "LocalizationManagement";
public const string Enable = GroupName + ".Enable";
}

3
aspnet-core/modules/localization-management/LINGYUN.Abp.LocalizationManagement.Domain.Shared/LINGYUN/Abp/LocalizationManagement/Localization/Resources/en.json

@ -6,6 +6,9 @@
"DisplayName:CreationTime": "Creation Time",
"DisplayName:LastModificationTime": "Modification Time",
"DisplayName:SaveAndNext": "Save & Next",
"Feature:LocalizationManagement": "Localization Management",
"Feature:LocalizationManagementEnable": "Enable Localization Management",
"Feature:LocalizationManagementEnableDesc": "Enable localization management in the application",
"Permissions:LocalizationManagement": "Localization",
"Permissions:Language": "Language",
"Permissions:Resource": "Resource",

3
aspnet-core/modules/localization-management/LINGYUN.Abp.LocalizationManagement.Domain.Shared/LINGYUN/Abp/LocalizationManagement/Localization/Resources/zh-Hans.json

@ -6,6 +6,9 @@
"DisplayName:CreationTime": "创建时间",
"DisplayName:LastModificationTime": "变更时间",
"DisplayName:SaveAndNext": "保存并下一步",
"Feature:LocalizationManagement": "本地化管理",
"Feature:LocalizationManagementEnable": "启用本地化管理",
"Feature:LocalizationManagementEnableDesc": "在应用程序中启用本地化管理",
"Permissions:LocalizationManagement": "本地化管理",
"Permissions:Language": "语言管理",
"Permissions:Resource": "资源管理",

69
aspnet-core/modules/localization-management/LINGYUN.Abp.LocalizationManagement.Domain/LINGYUN/Abp/LocalizationManagement/External/ExternalLocalizationResourceContributor.cs

@ -0,0 +1,69 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Localization;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp.Localization;
namespace LINGYUN.Abp.LocalizationManagement.External;
public class ExternalLocalizationResourceContributor : ILocalizationResourceContributor
{
public bool IsDynamic => false;
protected LocalizationResourceBase Resource { get; private set; }
protected IExternalLocalizationStoreCache StoreCache { get; private set; }
protected IExternalLocalizationTextStoreCache TextStoreCache { get; private set; }
public virtual void Fill(string cultureName, Dictionary<string, LocalizedString> dictionary)
{
var texts = TextStoreCache.GetTexts(Resource, cultureName);
foreach (var text in texts)
{
dictionary[text.Key] = new LocalizedString(text.Key, text.Value);
}
}
public async virtual Task FillAsync(string cultureName, Dictionary<string, LocalizedString> dictionary)
{
var texts = await TextStoreCache.GetTextsAsync(Resource, cultureName);
foreach (var text in texts)
{
dictionary[text.Key] = new LocalizedString(text.Key, text.Value);
}
}
public virtual LocalizedString GetOrNull(string cultureName, string name)
{
var texts = TextStoreCache.GetTexts(Resource, cultureName);
var text = texts.GetOrDefault(name);
if (text == null)
{
return null;
}
return new LocalizedString(name, text);
}
public async virtual Task<IEnumerable<string>> GetSupportedCulturesAsync()
{
var cacheItem = await StoreCache.GetResourceOrNullAsync(Resource.ResourceName);
if (cacheItem == null || !cacheItem.IsEnabled)
{
return Array.Empty<string>();
}
return cacheItem.SupportedCultures;
}
public void Initialize(LocalizationResourceInitializationContext context)
{
Resource = context.Resource;
StoreCache = context.ServiceProvider.GetRequiredService<IExternalLocalizationStoreCache>();
TextStoreCache = context.ServiceProvider.GetRequiredService<IExternalLocalizationTextStoreCache>();
}
}

90
aspnet-core/modules/localization-management/LINGYUN.Abp.LocalizationManagement.Domain/LINGYUN/Abp/LocalizationManagement/External/ExternalLocalizationStore.cs

@ -0,0 +1,90 @@
using Microsoft.Extensions.Options;
using System;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Localization;
using Volo.Abp.Localization.External;
namespace LINGYUN.Abp.LocalizationManagement.External;
[Dependency(ReplaceServices = true)]
public class ExternalLocalizationStore : IExternalLocalizationStore, ITransientDependency
{
protected AbpLocalizationOptions LocalizationOptions { get; }
protected IExternalLocalizationStoreCache StoreCache { get; }
public ExternalLocalizationStore(
IOptions<AbpLocalizationOptions> localizationOptions,
IExternalLocalizationStoreCache storeCache)
{
LocalizationOptions = localizationOptions.Value;
StoreCache = storeCache;
}
public virtual LocalizationResourceBase GetResourceOrNull(string resourceName)
{
var cacheItem = StoreCache.GetResourceOrNull(resourceName);
if (cacheItem == null || LocalizationOptions.Resources.ContainsKey(cacheItem.Name))
{
return null;
}
return CreateNonTypedLocalizationResource(cacheItem);
}
public async virtual Task<LocalizationResourceBase> GetResourceOrNullAsync(string resourceName)
{
var cacheItem = await StoreCache.GetResourceOrNullAsync(resourceName);
if (cacheItem == null || LocalizationOptions.Resources.ContainsKey(cacheItem.Name))
{
return null;
}
return CreateNonTypedLocalizationResource(cacheItem);
}
public async virtual Task<string[]> GetResourceNamesAsync()
{
var cacheNames = await StoreCache.GetResourceNamesAsync();
return cacheNames
.Where(name => !LocalizationOptions.Resources.ContainsKey(name))
.ToArray();
}
public async virtual Task<LocalizationResourceBase[]> GetResourcesAsync()
{
var cacheItem = await StoreCache.GetResourcesAsync();
if (cacheItem == null)
{
return Array.Empty<LocalizationResourceBase>();
}
return cacheItem
.Where(x => x.IsEnabled)
.Where(x => !LocalizationOptions.Resources.ContainsKey(x.Name))
.Select(CreateNonTypedLocalizationResource)
.ToArray();
}
protected virtual NonTypedLocalizationResource CreateNonTypedLocalizationResource(LocalizationResourceCacheItem cacheItem)
{
var localizationResource = new NonTypedLocalizationResource(
cacheItem.Name,
cacheItem.DefaultCulture);
if (cacheItem.BaseResources.Length > 0)
{
localizationResource.AddBaseResources(cacheItem.BaseResources);
}
localizationResource.Contributors.Add(new ExternalLocalizationResourceContributor());
return localizationResource;
}
}

146
aspnet-core/modules/localization-management/LINGYUN.Abp.LocalizationManagement.Domain/LINGYUN/Abp/LocalizationManagement/External/ExternalLocalizationStoreCache.cs

@ -0,0 +1,146 @@
using Microsoft.Extensions.Options;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.Caching;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Localization;
namespace LINGYUN.Abp.LocalizationManagement.External;
public class ExternalLocalizationStoreCache : IExternalLocalizationStoreCache, ITransientDependency
{
protected IDistributedCache<LocalizationResourceCacheItem> ResourceCache { get; }
protected IDistributedCache<LocalizationResourcesCacheItem> ResourcesCache { get; }
protected AbpLocalizationOptions LocalizationOptions { get; }
protected IResourceRepository ResourceRepository { get; }
public ExternalLocalizationStoreCache(
IDistributedCache<LocalizationResourcesCacheItem> resourcesCache,
IDistributedCache<LocalizationResourceCacheItem> resourceCache,
IOptions<AbpLocalizationOptions> localizationOptions,
IResourceRepository resourceRepository)
{
ResourceCache = resourceCache;
ResourcesCache = resourcesCache;
ResourceRepository = resourceRepository;
LocalizationOptions = localizationOptions.Value;
}
public async virtual Task RemoveAsync(string resourceName)
{
await ResourceCache.RemoveAsync(resourceName);
await ResourcesCache.RemoveAsync(LocalizationResourcesCacheItem.CacheKey);
}
public async virtual Task<string[]> GetResourceNamesAsync()
{
var cacheItem = await GetResourcesCacheItemAsync();
return cacheItem.Resources
.Where(x => x.IsEnabled)
.Where(x => !LocalizationOptions.Resources.ContainsKey(x.Name))
.Select(x => x.Name)
.ToArray();
}
public virtual LocalizationResourceCacheItem GetResourceOrNull(string resourceName)
{
var cacheItem = GetResourceCacheItem(resourceName);
return cacheItem.IsEnabled ? cacheItem : null;
}
public async virtual Task<LocalizationResourceCacheItem> GetResourceOrNullAsync(string resourceName)
{
var cacheItem = await GetResourceCacheItemAsync(resourceName);
return cacheItem.IsEnabled ? cacheItem : null;
}
public async virtual Task<LocalizationResourceCacheItem[]> GetResourcesAsync()
{
var cacheItem = await GetResourcesCacheItemAsync();
return cacheItem.Resources
.Where(x => x.IsEnabled)
.Where(x => !LocalizationOptions.Resources.ContainsKey(x.Name))
.ToArray();
}
protected virtual LocalizationResourceCacheItem GetResourceCacheItem(string resourceName)
{
var cacheItem = ResourceCache.Get(resourceName);
if (cacheItem == null)
{
var resource = ResourceRepository.FindByName(resourceName);
if (resource == null)
{
cacheItem = new LocalizationResourceCacheItem(resourceName)
{
IsEnabled = false
};
}
else
{
cacheItem = new LocalizationResourceCacheItem(resource.Name, resource.DefaultCultureName)
{
IsEnabled = resource.Enable
};
}
ResourceCache.Set(resourceName, cacheItem);
}
return cacheItem;
}
protected async virtual Task<LocalizationResourceCacheItem> GetResourceCacheItemAsync(string resourceName)
{
var cacheItem = await ResourceCache.GetAsync(resourceName);
if (cacheItem == null)
{
var resource = await ResourceRepository.FindByNameAsync(resourceName);
if (resource == null)
{
cacheItem = new LocalizationResourceCacheItem(resourceName)
{
IsEnabled = false
};
}
else
{
cacheItem = new LocalizationResourceCacheItem(resource.Name, resource.DefaultCultureName)
{
IsEnabled = resource.Enable
};
}
await ResourceCache.SetAsync(resourceName, cacheItem);
}
return cacheItem;
}
protected async virtual Task<LocalizationResourcesCacheItem> GetResourcesCacheItemAsync()
{
var cacheItem = await ResourcesCache.GetAsync(LocalizationResourcesCacheItem.CacheKey);
if (cacheItem == null)
{
var resources = await ResourceRepository.GetListAsync();
var resourceItems = resources
.Where(x => !LocalizationOptions.Resources.ContainsKey(x.Name))
.Select(x => new LocalizationResourceCacheItem(x.Name, x.DefaultCultureName)
{
IsEnabled = x.Enable,
})
.ToList();
cacheItem = new LocalizationResourcesCacheItem(resourceItems);
await ResourcesCache.SetAsync(LocalizationResourcesCacheItem.CacheKey, cacheItem);
}
return cacheItem;
}
}

29
aspnet-core/modules/localization-management/LINGYUN.Abp.LocalizationManagement.Domain/LINGYUN/Abp/LocalizationManagement/External/ExternalLocalizationTextCacheItem.cs

@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using Volo.Abp.Caching;
using Volo.Abp.MultiTenancy;
namespace LINGYUN.Abp.LocalizationManagement.External;
[Serializable]
[IgnoreMultiTenancy]
[CacheName("AbpExternalLocalizationTexts")]
public class ExternalLocalizationTextCacheItem
{
private const string CacheKeyFormat = "r:{0},c:{1}";
public Dictionary<string, string> Texts { get; set; }
public ExternalLocalizationTextCacheItem()
{
Texts = new Dictionary<string, string>();
}
public ExternalLocalizationTextCacheItem(Dictionary<string, string> texts)
{
Texts = texts;
}
public static string CalculateCacheKey(string resourceName, string cultureName)
{
return string.Format(CacheKeyFormat, resourceName, cultureName);
}
}

29
aspnet-core/modules/localization-management/LINGYUN.Abp.LocalizationManagement.Domain/LINGYUN/Abp/LocalizationManagement/External/ExternalLocalizationTextStampCacheItem.cs

@ -0,0 +1,29 @@
using System;
using Volo.Abp.Caching;
using Volo.Abp.MultiTenancy;
namespace LINGYUN.Abp.LocalizationManagement.External;
[Serializable]
[IgnoreMultiTenancy]
[CacheName("AbpExternalLocalizationTextsStamp")]
public class ExternalLocalizationTextStampCacheItem
{
private const string CacheKeyFormat = "r:{0},c:{1}";
public string Stamp { get; set; }
public ExternalLocalizationTextStampCacheItem()
{
}
public ExternalLocalizationTextStampCacheItem(string stamp)
{
Stamp = stamp;
}
public static string CalculateCacheKey(string resourceName, string cultureName)
{
return string.Format(CacheKeyFormat, resourceName, cultureName);
}
}

143
aspnet-core/modules/localization-management/LINGYUN.Abp.LocalizationManagement.Domain/LINGYUN/Abp/LocalizationManagement/External/ExternalLocalizationTextStoreCache.cs

@ -0,0 +1,143 @@
using AsyncKeyedLock;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp.Caching;
using Volo.Abp.DependencyInjection;
using Volo.Abp.DistributedLocking;
using Volo.Abp.Localization;
using Volo.Abp.Uow;
namespace LINGYUN.Abp.LocalizationManagement.External;
public class ExternalLocalizationTextStoreCache : IExternalLocalizationTextStoreCache, ISingletonDependency
{
protected AsyncKeyedLocker<string> AsyncKeyedLocker;
protected ConcurrentDictionary<string, LocalizationTextMemoryCacheItem> MemoryCache { get; }
protected IAbpDistributedLock DistributedLock { get; }
protected IServiceScopeFactory ServiceScopeFactory { get; }
protected IDistributedCache<ExternalLocalizationTextCacheItem> DistributedCache { get; }
protected IDistributedCache<ExternalLocalizationTextStampCacheItem> StampCache { get; }
public ExternalLocalizationTextStoreCache(
IAbpDistributedLock distributedLock,
IServiceScopeFactory serviceScopeFactory,
IDistributedCache<ExternalLocalizationTextCacheItem> distributedCache,
IDistributedCache<ExternalLocalizationTextStampCacheItem> stampCache)
{
DistributedLock = distributedLock;
ServiceScopeFactory = serviceScopeFactory;
DistributedCache = distributedCache;
StampCache = stampCache;
AsyncKeyedLocker = new AsyncKeyedLocker<string>(o =>
{
o.PoolSize = 20;
o.PoolInitialFill = 1;
});
MemoryCache = new ConcurrentDictionary<string, LocalizationTextMemoryCacheItem>();
}
public async virtual Task RemoveAsync(string resourceName, string cultureName)
{
var cacheKey = ExternalLocalizationTextCacheItem.CalculateCacheKey(resourceName, cultureName);
var stampCacheKey = ExternalLocalizationTextStampCacheItem.CalculateCacheKey(resourceName, cultureName);
await using var lockHandle = await DistributedLock.TryAcquireAsync(cacheKey, TimeSpan.FromMinutes(1d));
await DistributedCache.RemoveAsync(cacheKey);
await StampCache.SetAsync(stampCacheKey, new ExternalLocalizationTextStampCacheItem(Guid.NewGuid().ToString()));
}
public Dictionary<string, string> GetTexts(LocalizationResourceBase resource, string cultureName)
{
var cacheKey = ExternalLocalizationTextCacheItem.CalculateCacheKey(resource.ResourceName, cultureName);
var memoryCacheItem = MemoryCache.GetOrDefault(cacheKey);
if (memoryCacheItem != null && !IsShouldCheck(memoryCacheItem))
{
return memoryCacheItem.Texts;
}
return new Dictionary<string, string>();
}
public async virtual Task<Dictionary<string, string>> GetTextsAsync(LocalizationResourceBase resource, string cultureName)
{
var cacheKey = ExternalLocalizationTextCacheItem.CalculateCacheKey(resource.ResourceName, cultureName);
var memoryCacheItem = MemoryCache.GetOrDefault(cacheKey);
if (memoryCacheItem != null && !IsShouldCheck(memoryCacheItem))
{
return memoryCacheItem.Texts;
}
using (await AsyncKeyedLocker.LockAsync(cacheKey))
{
memoryCacheItem = MemoryCache.GetOrDefault(cacheKey);
if (memoryCacheItem != null && !IsShouldCheck(memoryCacheItem))
{
return memoryCacheItem.Texts;
}
var stampCacheKey = ExternalLocalizationTextStampCacheItem.CalculateCacheKey(resource.ResourceName, cultureName);
var stampCacheItem = await StampCache.GetAsync(stampCacheKey);
if (memoryCacheItem != null && memoryCacheItem.CacheStamp == stampCacheItem.Stamp)
{
memoryCacheItem.LastCheckTime = DateTime.Now;
return memoryCacheItem.Texts;
}
var distributeCacheItem = await DistributedCache.GetAsync(cacheKey);
if (distributeCacheItem != null)
{
MemoryCache[cacheKey] = new LocalizationTextMemoryCacheItem(distributeCacheItem.Texts, stampCacheItem.Stamp);
return distributeCacheItem.Texts;
}
await using var lockHandle = await DistributedLock.TryAcquireAsync(cacheKey, TimeSpan.FromMinutes(1d));
if (lockHandle == null)
{
return new Dictionary<string, string>();
}
distributeCacheItem = await CreateCacheItemAsync(resource, cultureName);
await DistributedCache.SetAsync(cacheKey, distributeCacheItem);
stampCacheItem = new ExternalLocalizationTextStampCacheItem(Guid.NewGuid().ToString());
await StampCache.SetAsync(stampCacheKey, stampCacheItem);
MemoryCache[cacheKey] = new LocalizationTextMemoryCacheItem(distributeCacheItem.Texts, stampCacheItem.Stamp);
return distributeCacheItem.Texts;
}
}
private static bool IsShouldCheck(LocalizationTextMemoryCacheItem memoryCacheItem)
{
return DateTime.Now.Subtract(memoryCacheItem.LastCheckTime).TotalSeconds >= 30.0;
}
protected async virtual Task<ExternalLocalizationTextCacheItem> CreateCacheItemAsync(LocalizationResourceBase resource, string cultureName)
{
using var scope = ServiceScopeFactory.CreateScope();
var unitOfWorkManager = scope.ServiceProvider.GetRequiredService<IUnitOfWorkManager>();
using var unitOfWork = unitOfWorkManager.Begin(requiresNew: true);
var repo = scope.ServiceProvider.GetRequiredService<ITextRepository>();
var texts = await repo.GetListAsync(resource.ResourceName, cultureName);
var fillTexts = new Dictionary<string, string>();
foreach (var text in texts)
{
fillTexts[text.Key] = text.Value;
}
return new ExternalLocalizationTextCacheItem(fillTexts);
}
}

16
aspnet-core/modules/localization-management/LINGYUN.Abp.LocalizationManagement.Domain/LINGYUN/Abp/LocalizationManagement/External/IExternalLocalizationStoreCache.cs

@ -0,0 +1,16 @@
using System.Threading.Tasks;
namespace LINGYUN.Abp.LocalizationManagement.External;
public interface IExternalLocalizationStoreCache
{
LocalizationResourceCacheItem GetResourceOrNull(string resourceName);
Task<LocalizationResourceCacheItem> GetResourceOrNullAsync(string resourceName);
Task<string[]> GetResourceNamesAsync();
Task<LocalizationResourceCacheItem[]> GetResourcesAsync();
Task RemoveAsync(string resourceName);
}

14
aspnet-core/modules/localization-management/LINGYUN.Abp.LocalizationManagement.Domain/LINGYUN/Abp/LocalizationManagement/External/IExternalLocalizationTextStoreCache.cs

@ -0,0 +1,14 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp.Localization;
namespace LINGYUN.Abp.LocalizationManagement.External;
public interface IExternalLocalizationTextStoreCache
{
Dictionary<string, string> GetTexts(LocalizationResourceBase resource, string cultureName);
Task<Dictionary<string, string>> GetTextsAsync(LocalizationResourceBase resource, string cultureName);
Task RemoveAsync(string resourceName, string cultureName);
}

36
aspnet-core/modules/localization-management/LINGYUN.Abp.LocalizationManagement.Domain/LINGYUN/Abp/LocalizationManagement/External/LocalizationResourceCacheInvalidator.cs

@ -0,0 +1,36 @@
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Entities.Events;
using Volo.Abp.EventBus;
namespace LINGYUN.Abp.LocalizationManagement.External;
public class LocalizationResourceCacheInvalidator :
ILocalEventHandler<EntityChangedEventData<Resource>>,
ITransientDependency
{
private readonly IExternalLocalizationTextStoreCache _externalLocalizationTextStoreCache;
private readonly ILocalizationLanguageStoreCache _localizationLanguageStoreCache;
private readonly IExternalLocalizationStoreCache _externalLocalizationStoreCache;
public LocalizationResourceCacheInvalidator(
IExternalLocalizationTextStoreCache externalLocalizationTextStoreCache,
ILocalizationLanguageStoreCache localizationLanguageStoreCache,
IExternalLocalizationStoreCache externalLocalizationStoreCache)
{
_externalLocalizationTextStoreCache = externalLocalizationTextStoreCache;
_localizationLanguageStoreCache = localizationLanguageStoreCache;
_externalLocalizationStoreCache = externalLocalizationStoreCache;
}
public async virtual Task HandleEventAsync(EntityChangedEventData<Resource> eventData)
{
await _externalLocalizationStoreCache.RemoveAsync(eventData.Entity.Name);
;
var languages = await _localizationLanguageStoreCache.GetLanguagesAsync();
foreach (var language in languages)
{
await _externalLocalizationTextStoreCache.RemoveAsync(eventData.Entity.Name, language.CultureName);
}
}
}

32
aspnet-core/modules/localization-management/LINGYUN.Abp.LocalizationManagement.Domain/LINGYUN/Abp/LocalizationManagement/External/LocalizationResourceCacheItem.cs

@ -0,0 +1,32 @@
using System;
using Volo.Abp.Caching;
using Volo.Abp.MultiTenancy;
namespace LINGYUN.Abp.LocalizationManagement.External;
[IgnoreMultiTenancy]
[CacheName("AbpExternalLocalizationResource")]
public class LocalizationResourceCacheItem
{
public virtual string Name { get; set; }
public virtual string DefaultCulture { get; set; }
public virtual string[] BaseResources { get; set; }
public virtual string[] SupportedCultures { get; set; }
public bool IsEnabled { get; set; }
public LocalizationResourceCacheItem(
string name,
string defaultCulture = null,
string[] baseResources = null,
string[] supportedCultures = null)
{
Name = name;
DefaultCulture = defaultCulture;
BaseResources = baseResources ?? Array.Empty<string>();
SupportedCultures = supportedCultures ?? Array.Empty<string>();
}
}

30
aspnet-core/modules/localization-management/LINGYUN.Abp.LocalizationManagement.Domain/LINGYUN/Abp/LocalizationManagement/External/LocalizationResourcesCacheItem.cs

@ -0,0 +1,30 @@
using System.Collections.Generic;
using System.Linq;
using Volo.Abp.Caching;
using Volo.Abp.MultiTenancy;
namespace LINGYUN.Abp.LocalizationManagement.External;
[IgnoreMultiTenancy]
[CacheName("AbpExternalLocalizationResources")]
public class LocalizationResourcesCacheItem
{
public const string CacheKey = "All";
public List<LocalizationResourceCacheItem> Resources { get; set; }
public LocalizationResourcesCacheItem()
{
Resources = new List<LocalizationResourceCacheItem>();
}
public LocalizationResourcesCacheItem(List<LocalizationResourceCacheItem> resources)
{
Resources = resources;
}
public LocalizationResourceCacheItem GetResourceOrNull(string name)
{
return Resources?.FirstOrDefault(x => x.Name == name);
}
}

31
aspnet-core/modules/localization-management/LINGYUN.Abp.LocalizationManagement.Domain/LINGYUN/Abp/LocalizationManagement/External/LocalizationTextMemoryCacheItem.cs

@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
namespace LINGYUN.Abp.LocalizationManagement.External;
public class LocalizationTextMemoryCacheItem
{
private const string CacheKeyFormat = "r:{0},c:{1}";
public string CacheStamp { get; }
public DateTime LastCheckTime { get; set; }
public Dictionary<string, string> Texts { get; set; }
public LocalizationTextMemoryCacheItem()
{
Texts = new Dictionary<string, string>();
}
public LocalizationTextMemoryCacheItem(Dictionary<string, string> texts, string cacheStamp)
{
Texts = texts;
CacheStamp = cacheStamp;
LastCheckTime = DateTime.Now;
}
public static string CalculateCacheKey(string resourceName, string cultureName)
{
return string.Format(CacheKeyFormat, resourceName, cultureName);
}
}

2
aspnet-core/modules/localization-management/LINGYUN.Abp.LocalizationManagement.Domain/LINGYUN/Abp/LocalizationManagement/IResourceRepository.cs

@ -11,6 +11,8 @@ public interface IResourceRepository : IRepository<Resource, Guid>
string name,
CancellationToken cancellationToken = default);
Resource FindByName(string name);
Task<Resource> FindByNameAsync(
string name,
CancellationToken cancellationToken = default);

4
aspnet-core/modules/localization-management/LINGYUN.Abp.LocalizationManagement.Domain/LINGYUN/Abp/LocalizationManagement/LocalizationLanguageCacheItem.cs

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using Volo.Abp.Caching;
using Volo.Abp.Localization;
using Volo.Abp.MultiTenancy;
@ -7,9 +8,10 @@ namespace LINGYUN.Abp.LocalizationManagement;
[Serializable]
[IgnoreMultiTenancy]
[CacheName("AbpLocalizationLanguages")]
public class LocalizationLanguageCacheItem
{
internal const string CacheKey = "Abp.Localization.Languages";
public const string CacheKey = "All";
public List<LanguageInfo> Languages { get; set; }
public LocalizationLanguageCacheItem()

11
aspnet-core/modules/localization-management/LINGYUN.Abp.LocalizationManagement.Domain/LINGYUN/Abp/LocalizationManagement/LocalizationTextCacheInvalidator.cs

@ -1,4 +1,5 @@
using System.Threading.Tasks;
using LINGYUN.Abp.LocalizationManagement.External;
using System.Threading.Tasks;
using Volo.Abp.Caching;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Entities.Events;
@ -9,8 +10,12 @@ namespace LINGYUN.Abp.LocalizationManagement;
public class LocalizationTextCacheInvalidator : ILocalEventHandler<EntityChangedEventData<Text>>, ITransientDependency
{
private readonly IDistributedCache<LocalizationTextCacheItem> _localizationTextCache;
public LocalizationTextCacheInvalidator(IDistributedCache<LocalizationTextCacheItem> localizationTextCache)
private readonly IExternalLocalizationTextStoreCache _externalLocalizationTextStoreCache;
public LocalizationTextCacheInvalidator(
IDistributedCache<LocalizationTextCacheItem> localizationTextCache,
IExternalLocalizationTextStoreCache externalLocalizationTextStoreCache)
{
_externalLocalizationTextStoreCache = externalLocalizationTextStoreCache;
_localizationTextCache = localizationTextCache;
}
@ -21,5 +26,7 @@ public class LocalizationTextCacheInvalidator : ILocalEventHandler<EntityChanged
eventData.Entity.CultureName);
await _localizationTextCache.RemoveAsync(cacheKey);
await _externalLocalizationTextStoreCache.RemoveAsync(eventData.Entity.ResourceName, eventData.Entity.CultureName);
}
}

2
aspnet-core/modules/localization-management/LINGYUN.Abp.LocalizationManagement.Domain/LINGYUN/Abp/LocalizationManagement/LocalizationTextCacheItem.cs

@ -1,11 +1,13 @@
using System;
using System.Collections.Generic;
using Volo.Abp.Caching;
using Volo.Abp.MultiTenancy;
namespace LINGYUN.Abp.LocalizationManagement;
[Serializable]
[IgnoreMultiTenancy]
[CacheName("AbpLocalizationTexts")]
public class LocalizationTextCacheItem
{
private const string CacheKeyFormat = "r:{0},c:{1}";

10
aspnet-core/modules/localization-management/LINGYUN.Abp.LocalizationManagement.EntityFrameworkCore/LINGYUN/Abp/LocalizationManagement/EntityFrameworkCore/EfCoreResourceRepository.cs

@ -5,6 +5,7 @@ using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.Threading;
namespace LINGYUN.Abp.LocalizationManagement.EntityFrameworkCore;
@ -23,6 +24,15 @@ public class EfCoreResourceRepository : EfCoreRepository<LocalizationDbContext,
return await (await GetDbSetAsync()).AnyAsync(x => x.Name.Equals(name));
}
[Obsolete("Use FindAsync() method.")]
public virtual Resource FindByName(string name)
{
using (Volo.Abp.Uow.UnitOfWorkManager.DisableObsoleteDbContextCreationWarning.SetScoped(true))
{
return DbSet.FirstOrDefault(localizationResourceRecord => localizationResourceRecord.Name == name);
}
}
public async virtual Task<Resource> FindByNameAsync(
string name,
CancellationToken cancellationToken = default)

Loading…
Cancel
Save