21 changed files with 682 additions and 642 deletions
@ -0,0 +1,5 @@ |
|||||
|
namespace LINGYUN.Abp.LocalizationManagement; |
||||
|
|
||||
|
public class DynamicLocalizationChangedEto |
||||
|
{ |
||||
|
} |
||||
@ -0,0 +1,53 @@ |
|||||
|
namespace LINGYUN.Abp.LocalizationManagement; |
||||
|
|
||||
|
public abstract class DynamicLocalizationInitializerEto |
||||
|
{ |
||||
|
public string[] Keys { get; set; } |
||||
|
protected DynamicLocalizationInitializerEto() |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
protected DynamicLocalizationInitializerEto(string[] keys) |
||||
|
{ |
||||
|
Keys = keys; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public class DynamicLanguageInitializerEto : DynamicLocalizationInitializerEto |
||||
|
{ |
||||
|
public DynamicLanguageInitializerEto() |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public DynamicLanguageInitializerEto(string[] keys) : base(keys) |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
public class DynamicResourceInitializerEto : DynamicLocalizationInitializerEto |
||||
|
{ |
||||
|
public DynamicResourceInitializerEto() |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public DynamicResourceInitializerEto(string[] keys) : base(keys) |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
public class DynamicTextInitializerEto : DynamicLocalizationInitializerEto |
||||
|
{ |
||||
|
public DynamicTextInitializerEto() |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public DynamicTextInitializerEto(string[] keys) : base(keys) |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,11 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
|
||||
|
namespace LINGYUN.Abp.LocalizationManagement; |
||||
|
|
||||
|
[Serializable] |
||||
|
public class ResourceChangedEto |
||||
|
{ |
||||
|
public List<string> Resources { get; set; } |
||||
|
public List<string> Cultures { get; set; } |
||||
|
} |
||||
@ -0,0 +1,51 @@ |
|||||
|
using LINGYUN.Abp.LocalizationManagement.External; |
||||
|
using System.Threading.Tasks; |
||||
|
using Volo.Abp.Caching; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
using Volo.Abp.EventBus.Distributed; |
||||
|
|
||||
|
namespace LINGYUN.Abp.LocalizationManagement; |
||||
|
|
||||
|
public class DynamicLocalizationChangedEventHandler : |
||||
|
IDistributedEventHandler<DynamicLocalizationChangedEto>, |
||||
|
ITransientDependency |
||||
|
{ |
||||
|
protected IDistributedCache<LocalizationResourcesCacheItem> ResourcesCache { get; } |
||||
|
protected IDistributedCache<LocalizationLanguageCacheItem> LanguageCache { get; } |
||||
|
|
||||
|
protected IExternalLocalizationTextStoreCache ExternalLocalizationTextStoreCache { get; } |
||||
|
protected ILocalizationTextStoreCache LocalizationTextStoreCache { get; } |
||||
|
|
||||
|
public DynamicLocalizationChangedEventHandler( |
||||
|
IDistributedCache<LocalizationResourcesCacheItem> resourcesCache, |
||||
|
IDistributedCache<LocalizationLanguageCacheItem> languageCache, |
||||
|
IExternalLocalizationTextStoreCache externalLocalizationTextStoreCache, |
||||
|
ILocalizationTextStoreCache localizationTextStoreCache) |
||||
|
{ |
||||
|
ResourcesCache = resourcesCache; |
||||
|
LanguageCache = languageCache; |
||||
|
ExternalLocalizationTextStoreCache = externalLocalizationTextStoreCache; |
||||
|
LocalizationTextStoreCache = localizationTextStoreCache; |
||||
|
} |
||||
|
|
||||
|
public async virtual Task HandleEventAsync(DynamicLocalizationChangedEto eventData) |
||||
|
{ |
||||
|
var resourcesCacheItem = await ResourcesCache.GetAsync(LocalizationResourcesCacheItem.CacheKey); |
||||
|
var languagesCacheItem = await LanguageCache.GetAsync(LocalizationLanguageCacheItem.CacheKey); |
||||
|
|
||||
|
foreach (var language in languagesCacheItem.Languages) |
||||
|
{ |
||||
|
foreach (var resource in resourcesCacheItem.Resources) |
||||
|
{ |
||||
|
if (ExternalLocalizationTextStoreCache is ExternalLocalizationTextStoreCache storeCache) |
||||
|
{ |
||||
|
await storeCache.UpdateCache(resource.Name, language.CultureName); |
||||
|
} |
||||
|
if (LocalizationTextStoreCache is LocalizationTextStoreCache textStoreCache) |
||||
|
{ |
||||
|
await textStoreCache.UpdateCache(resource.Name, language.CultureName); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,73 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using Volo.Abp.Caching; |
||||
|
using Volo.Abp.MultiTenancy; |
||||
|
|
||||
|
namespace LINGYUN.Abp.LocalizationManagement; |
||||
|
|
||||
|
[Serializable] |
||||
|
[IgnoreMultiTenancy] |
||||
|
[CacheName("DynamicLanguageInitializer")] |
||||
|
public class DynamicLanguageInitializerCacheItem |
||||
|
{ |
||||
|
public string CultureName { get; set; } |
||||
|
public string UiCultureName { get; set; } |
||||
|
public string DisplayName { get; set; } |
||||
|
public string TwoLetterISOLanguageName { get; set; } |
||||
|
public DynamicLanguageInitializerCacheItem() |
||||
|
{ |
||||
|
} |
||||
|
public DynamicLanguageInitializerCacheItem( |
||||
|
string cultureName, |
||||
|
string uiCultureName, |
||||
|
string displayName, |
||||
|
string twoLetterISOLanguageName) |
||||
|
{ |
||||
|
CultureName = cultureName; |
||||
|
UiCultureName = uiCultureName; |
||||
|
DisplayName = displayName; |
||||
|
TwoLetterISOLanguageName = twoLetterISOLanguageName; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
[Serializable] |
||||
|
[IgnoreMultiTenancy] |
||||
|
[CacheName("DynamicResourceInitializer")] |
||||
|
public class DynamicResourceInitializerCacheItem |
||||
|
{ |
||||
|
public string ResourceName { get; set; } |
||||
|
public string DefaultCultureName { get; set; } |
||||
|
public DynamicResourceInitializerCacheItem() |
||||
|
{ |
||||
|
} |
||||
|
public DynamicResourceInitializerCacheItem( |
||||
|
string resourceName, |
||||
|
string defaultCultureName) |
||||
|
{ |
||||
|
ResourceName = resourceName; |
||||
|
DefaultCultureName = defaultCultureName; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
[Serializable] |
||||
|
[IgnoreMultiTenancy] |
||||
|
[CacheName("DynamicTextInitializer")] |
||||
|
public class DynamicTextInitializerCacheItem |
||||
|
{ |
||||
|
public string ResourceName { get; set; } |
||||
|
public string CultureName { get; set; } |
||||
|
public Dictionary<string, string> Texts { get; set; } |
||||
|
public DynamicTextInitializerCacheItem() |
||||
|
{ |
||||
|
Texts = new Dictionary<string, string>(); |
||||
|
} |
||||
|
public DynamicTextInitializerCacheItem( |
||||
|
string resourceName, |
||||
|
string cultureName, |
||||
|
Dictionary<string, string> texts) |
||||
|
{ |
||||
|
ResourceName = resourceName; |
||||
|
CultureName = cultureName; |
||||
|
Texts = texts; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,379 @@ |
|||||
|
using LINGYUN.Abp.LocalizationManagement.External; |
||||
|
using Microsoft.Extensions.Logging; |
||||
|
using Microsoft.Extensions.Logging.Abstractions; |
||||
|
using Microsoft.Extensions.Options; |
||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Threading.Tasks; |
||||
|
using Volo.Abp; |
||||
|
using Volo.Abp.Caching; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
using Volo.Abp.DistributedLocking; |
||||
|
using Volo.Abp.EventBus.Distributed; |
||||
|
using Volo.Abp.Guids; |
||||
|
using Volo.Abp.Localization; |
||||
|
using Volo.Abp.Uow; |
||||
|
|
||||
|
namespace LINGYUN.Abp.LocalizationManagement; |
||||
|
|
||||
|
public class DynamicLocalizationInitializerEeventHandler : |
||||
|
IDistributedEventHandler<DynamicLanguageInitializerEto>, |
||||
|
IDistributedEventHandler<DynamicResourceInitializerEto>, |
||||
|
IDistributedEventHandler<DynamicTextInitializerEto>, |
||||
|
ITransientDependency |
||||
|
{ |
||||
|
public ILogger<StaticLocalizationSaver> Logger { protected get; set; } |
||||
|
|
||||
|
protected IDistributedCache<LocalizationResourceCacheItem> ResourceCache { get; } |
||||
|
protected IDistributedCache<LocalizationResourcesCacheItem> ResourcesCache { get; } |
||||
|
protected IDistributedCache<LocalizationLanguageCacheItem> LanguageCache { get; } |
||||
|
protected IDistributedCache<LocalizationTextCacheItem> LocalizationTextCache { get; } |
||||
|
|
||||
|
protected IDistributedCache<DynamicLanguageInitializerCacheItem> DynamicLanguageCache { get; } |
||||
|
protected IDistributedCache<DynamicResourceInitializerCacheItem> DynamicResourceCache { get; } |
||||
|
protected IDistributedCache<DynamicTextInitializerCacheItem> DynamicTextCache { get; } |
||||
|
|
||||
|
protected AbpLocalizationManagementOptions LocalizationManagementOptions { get; } |
||||
|
|
||||
|
protected IGuidGenerator GuidGenerator { get; } |
||||
|
protected IAbpDistributedLock DistributedLock { get; } |
||||
|
protected IDistributedEventBus DistributedEventBus { get; } |
||||
|
protected IUnitOfWorkManager UnitOfWorkManager { get; } |
||||
|
|
||||
|
protected ILanguageRepository LanguageRepository { get; } |
||||
|
protected IResourceRepository ResourceRepository { get; } |
||||
|
protected ITextRepository TextRepository { get; } |
||||
|
|
||||
|
public DynamicLocalizationInitializerEeventHandler( |
||||
|
IDistributedCache<LocalizationResourceCacheItem> resourceCache, |
||||
|
IDistributedCache<LocalizationResourcesCacheItem> resourcesCache, |
||||
|
IDistributedCache<LocalizationLanguageCacheItem> languageCache, |
||||
|
IDistributedCache<LocalizationTextCacheItem> localizationTextCache, |
||||
|
IDistributedCache<DynamicLanguageInitializerCacheItem> dynamicLanguageCache, |
||||
|
IDistributedCache<DynamicResourceInitializerCacheItem> dynamicResourceCache, |
||||
|
IDistributedCache<DynamicTextInitializerCacheItem> dynamicTextCache, |
||||
|
IOptions<AbpLocalizationManagementOptions> localizationManagementOptions, |
||||
|
IGuidGenerator guidGenerator, |
||||
|
IAbpDistributedLock distributedLock, |
||||
|
IDistributedEventBus distributedEventBus, |
||||
|
IUnitOfWorkManager unitOfWorkManager, |
||||
|
ILanguageRepository languageRepository, |
||||
|
IResourceRepository resourceRepository, |
||||
|
ITextRepository textRepository) |
||||
|
{ |
||||
|
ResourceCache = resourceCache; |
||||
|
ResourcesCache = resourcesCache; |
||||
|
LanguageCache = languageCache; |
||||
|
LocalizationTextCache = localizationTextCache; |
||||
|
DynamicLanguageCache = dynamicLanguageCache; |
||||
|
DynamicResourceCache = dynamicResourceCache; |
||||
|
DynamicTextCache = dynamicTextCache; |
||||
|
LocalizationManagementOptions = localizationManagementOptions.Value; |
||||
|
GuidGenerator = guidGenerator; |
||||
|
DistributedLock = distributedLock; |
||||
|
DistributedEventBus = distributedEventBus; |
||||
|
UnitOfWorkManager = unitOfWorkManager; |
||||
|
LanguageRepository = languageRepository; |
||||
|
ResourceRepository = resourceRepository; |
||||
|
TextRepository = textRepository; |
||||
|
|
||||
|
Logger = NullLogger<StaticLocalizationSaver>.Instance; |
||||
|
} |
||||
|
|
||||
|
public async virtual Task HandleEventAsync(DynamicLanguageInitializerEto eventData) |
||||
|
{ |
||||
|
if (!LocalizationManagementOptions.SaveStaticLocalizationsToDatabase || |
||||
|
!LocalizationManagementOptions.IsDynamicLocalizationInitializerHost) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
Logger.LogDebug("Waiting to acquire the distributed lock for saving static languages..."); |
||||
|
|
||||
|
await using var applicationLockHandle = await DistributedLock.TryAcquireAsync( |
||||
|
$"{nameof(DynamicLocalizationInitializerEeventHandler)}_{nameof(DynamicLanguageInitializerEto)}", |
||||
|
TimeSpan.FromSeconds(5)); |
||||
|
if (applicationLockHandle == null) |
||||
|
{ |
||||
|
throw new AbpException("Failed to acquire the initialization lock for the localization languages!"); |
||||
|
} |
||||
|
|
||||
|
using var unitOfWork = UnitOfWorkManager.Begin(true, true); |
||||
|
|
||||
|
var cacheItems = await DynamicLanguageCache.GetManyAsync(eventData.Keys); |
||||
|
|
||||
|
await SaveLanguagesAsync(cacheItems.Select(kv => kv.Value).ToArray()); |
||||
|
|
||||
|
Logger.LogInformation("Refresh language cache items."); |
||||
|
await RefreshLanguagesCacheAsync(); |
||||
|
|
||||
|
await DynamicLanguageCache.RemoveManyAsync(eventData.Keys); |
||||
|
|
||||
|
await DistributedEventBus.PublishAsync(new DynamicLocalizationChangedEto()); |
||||
|
|
||||
|
await unitOfWork.CompleteAsync(); |
||||
|
|
||||
|
Logger.LogInformation("Completed to save static languages."); |
||||
|
} |
||||
|
|
||||
|
public async virtual Task HandleEventAsync(DynamicResourceInitializerEto eventData) |
||||
|
{ |
||||
|
if (!LocalizationManagementOptions.SaveStaticLocalizationsToDatabase || |
||||
|
!LocalizationManagementOptions.IsDynamicLocalizationInitializerHost) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
Logger.LogDebug("Waiting to acquire the distributed lock for saving static resources..."); |
||||
|
|
||||
|
await using var applicationLockHandle = await DistributedLock.TryAcquireAsync( |
||||
|
$"{nameof(DynamicLocalizationInitializerEeventHandler)}_{nameof(DynamicResourceInitializerEto)}", |
||||
|
TimeSpan.FromSeconds(5)); |
||||
|
if (applicationLockHandle == null) |
||||
|
{ |
||||
|
throw new AbpException("Failed to acquire the initialization lock for the localization resources!"); |
||||
|
} |
||||
|
|
||||
|
using var unitOfWork = UnitOfWorkManager.Begin(true, true); |
||||
|
|
||||
|
var cacheItems = await DynamicResourceCache.GetManyAsync(eventData.Keys); |
||||
|
|
||||
|
await SaveResourcesAsync(cacheItems.Select(kv => kv.Value).ToArray()); |
||||
|
|
||||
|
Logger.LogInformation("Refresh resource cache items."); |
||||
|
await RefreshResourcesCacheAsync(); |
||||
|
|
||||
|
await DynamicResourceCache.RemoveManyAsync(eventData.Keys); |
||||
|
|
||||
|
await DistributedEventBus.PublishAsync(new DynamicLocalizationChangedEto()); |
||||
|
|
||||
|
await unitOfWork.CompleteAsync(); |
||||
|
|
||||
|
Logger.LogInformation("Completed to save static resources."); |
||||
|
} |
||||
|
|
||||
|
public async virtual Task HandleEventAsync(DynamicTextInitializerEto eventData) |
||||
|
{ |
||||
|
if (!LocalizationManagementOptions.SaveStaticLocalizationsToDatabase || |
||||
|
!LocalizationManagementOptions.IsDynamicLocalizationInitializerHost) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
Logger.LogDebug("Waiting to acquire the distributed lock for saving static texts..."); |
||||
|
|
||||
|
await using var applicationLockHandle = await DistributedLock.TryAcquireAsync( |
||||
|
$"{nameof(DynamicLocalizationInitializerEeventHandler)}_{nameof(DynamicTextInitializerEto)}", |
||||
|
TimeSpan.FromSeconds(5)); |
||||
|
if (applicationLockHandle == null) |
||||
|
{ |
||||
|
throw new AbpException("Failed to acquire the initialization lock for the localization texts!"); |
||||
|
} |
||||
|
|
||||
|
using var unitOfWork = UnitOfWorkManager.Begin(true, true); |
||||
|
|
||||
|
var cacheItemDics = await DynamicTextCache.GetManyAsync(eventData.Keys); |
||||
|
var cacheItems = cacheItemDics.Select(kv => kv.Value).ToArray(); |
||||
|
|
||||
|
await SaveTextsAsync(cacheItems); |
||||
|
|
||||
|
Logger.LogInformation("Refresh text cache items."); |
||||
|
await RefreshTextsCacheAsync(cacheItems); |
||||
|
|
||||
|
await DynamicResourceCache.RemoveManyAsync(eventData.Keys); |
||||
|
|
||||
|
await DistributedEventBus.PublishAsync(new DynamicLocalizationChangedEto()); |
||||
|
|
||||
|
await unitOfWork.CompleteAsync(); |
||||
|
|
||||
|
Logger.LogInformation("Completed to save static texts."); |
||||
|
} |
||||
|
|
||||
|
private async Task SaveLanguagesAsync(DynamicLanguageInitializerCacheItem[] cacheItems) |
||||
|
{ |
||||
|
var newLanguages = new List<Language>(); |
||||
|
var updateLanguages = new List<Language>(); |
||||
|
var existsLanguages = await LanguageRepository.GetListAsync(); |
||||
|
foreach (var cacheItem in cacheItems) |
||||
|
{ |
||||
|
var existsLanguage = existsLanguages.FirstOrDefault(x => x.CultureName == cacheItem.CultureName); |
||||
|
if (existsLanguage == null) |
||||
|
{ |
||||
|
newLanguages.Add( |
||||
|
new Language( |
||||
|
GuidGenerator.Create(), |
||||
|
cacheItem.CultureName, |
||||
|
cacheItem.UiCultureName, |
||||
|
cacheItem.DisplayName, |
||||
|
cacheItem.TwoLetterISOLanguageName)); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
var isUpdated = false; |
||||
|
if (existsLanguage.DisplayName != cacheItem.DisplayName) |
||||
|
{ |
||||
|
isUpdated = true; |
||||
|
existsLanguage.SetDisplayName(cacheItem.DisplayName); |
||||
|
} |
||||
|
if (existsLanguage.TwoLetterISOLanguageName != cacheItem.TwoLetterISOLanguageName) |
||||
|
{ |
||||
|
isUpdated = true; |
||||
|
existsLanguage.SetTwoLetterISOLanguageName(cacheItem.TwoLetterISOLanguageName); |
||||
|
} |
||||
|
if (isUpdated) |
||||
|
{ |
||||
|
updateLanguages.Add(existsLanguage); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (newLanguages.Count > 0) |
||||
|
{ |
||||
|
Logger.LogInformation("Saved {0} new languages.", newLanguages.Count); |
||||
|
await LanguageRepository.InsertManyAsync(newLanguages, autoSave: true); |
||||
|
} |
||||
|
|
||||
|
if (updateLanguages.Count > 0) |
||||
|
{ |
||||
|
Logger.LogInformation("Update {0} changed languages.", updateLanguages.Count); |
||||
|
await LanguageRepository.UpdateManyAsync(updateLanguages, autoSave: true); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private async Task RefreshLanguagesCacheAsync() |
||||
|
{ |
||||
|
var languages = await LanguageRepository.GetListAsync(); |
||||
|
|
||||
|
var languageCacheItem = new LocalizationLanguageCacheItem( |
||||
|
languages.Select(x => |
||||
|
new LanguageInfo(x.CultureName, x.UiCultureName, x.DisplayName)) |
||||
|
.ToList()); |
||||
|
|
||||
|
await LanguageCache.SetAsync(LocalizationLanguageCacheItem.CacheKey, languageCacheItem); |
||||
|
} |
||||
|
|
||||
|
private async Task SaveResourcesAsync(DynamicResourceInitializerCacheItem[] cacheItems) |
||||
|
{ |
||||
|
var newResources = new List<Resource>(); |
||||
|
var updateResources = new List<Resource>(); |
||||
|
var existsResources = await ResourceRepository.GetListAsync(); |
||||
|
|
||||
|
foreach (var cacheItem in cacheItems) |
||||
|
{ |
||||
|
var existsResource = existsResources.FirstOrDefault(x => x.Name == cacheItem.ResourceName); |
||||
|
if (existsResource == null) |
||||
|
{ |
||||
|
newResources.Add( |
||||
|
new Resource( |
||||
|
GuidGenerator.Create(), |
||||
|
cacheItem.ResourceName, |
||||
|
cacheItem.ResourceName, |
||||
|
cacheItem.ResourceName, |
||||
|
cacheItem.DefaultCultureName)); |
||||
|
} |
||||
|
else if (existsResource.DefaultCultureName != cacheItem.DefaultCultureName) |
||||
|
{ |
||||
|
existsResource.SetDefaultCultureName(cacheItem.DefaultCultureName); |
||||
|
updateResources.Add(existsResource); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (newResources.Count > 0) |
||||
|
{ |
||||
|
Logger.LogInformation("Saved {0} new resources.", newResources.Count); |
||||
|
await ResourceRepository.InsertManyAsync(newResources, autoSave: true); |
||||
|
} |
||||
|
|
||||
|
if (updateResources.Count > 0) |
||||
|
{ |
||||
|
Logger.LogInformation("Update {0} changed resources.", updateResources.Count); |
||||
|
await ResourceRepository.UpdateManyAsync(updateResources, autoSave: true); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private async Task RefreshResourcesCacheAsync() |
||||
|
{ |
||||
|
var resources = await ResourceRepository.GetListAsync(); |
||||
|
|
||||
|
var allResourceCacheItems = new List<LocalizationResourceCacheItem>(); |
||||
|
var allResourceCacheItemDics = new Dictionary<string, LocalizationResourceCacheItem>(); |
||||
|
foreach (var resource in resources) |
||||
|
{ |
||||
|
var resourceCacheItem = new LocalizationResourceCacheItem(resource.Name, resource.DefaultCultureName) |
||||
|
{ |
||||
|
IsEnabled = resource.Enable |
||||
|
}; |
||||
|
allResourceCacheItems.Add(resourceCacheItem); |
||||
|
allResourceCacheItemDics[resource.Name] = resourceCacheItem; |
||||
|
} |
||||
|
|
||||
|
await ResourcesCache.SetAsync( |
||||
|
LocalizationResourcesCacheItem.CacheKey, |
||||
|
new LocalizationResourcesCacheItem(allResourceCacheItems)); |
||||
|
|
||||
|
await ResourceCache.SetManyAsync(allResourceCacheItemDics); |
||||
|
} |
||||
|
|
||||
|
private async Task SaveTextsAsync(DynamicTextInitializerCacheItem[] cacheItems) |
||||
|
{ |
||||
|
var newTexts = new List<Text>(); |
||||
|
var updateTexts = new List<Text>(); |
||||
|
|
||||
|
foreach (var cacheItem in cacheItems) |
||||
|
{ |
||||
|
var existsTexts = await TextRepository.GetListAsync( |
||||
|
cacheItem.ResourceName, |
||||
|
cacheItem.CultureName); |
||||
|
|
||||
|
foreach (var text in cacheItem.Texts) |
||||
|
{ |
||||
|
var existsText = existsTexts.FirstOrDefault(x => x.Key == text.Key); |
||||
|
if (existsText == null) |
||||
|
{ |
||||
|
newTexts.Add( |
||||
|
new Text( |
||||
|
cacheItem.ResourceName, |
||||
|
cacheItem.CultureName, |
||||
|
text.Key, |
||||
|
text.Value)); |
||||
|
} |
||||
|
else if (existsText.Value != text.Value) |
||||
|
{ |
||||
|
existsText.SetValue(text.Value); |
||||
|
updateTexts.Add(existsText); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (newTexts.Count > 0) |
||||
|
{ |
||||
|
Logger.LogInformation("Saved {0} new texts.", newTexts.Count); |
||||
|
await TextRepository.InsertManyAsync(newTexts, autoSave: true); |
||||
|
} |
||||
|
|
||||
|
if (updateTexts.Count > 0) |
||||
|
{ |
||||
|
Logger.LogInformation("Update {0} changed texts.", updateTexts.Count); |
||||
|
await TextRepository.UpdateManyAsync(updateTexts, autoSave: true); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private async Task RefreshTextsCacheAsync(DynamicTextInitializerCacheItem[] cacheItems) |
||||
|
{ |
||||
|
foreach (var cacheItem in cacheItems) |
||||
|
{ |
||||
|
var setTexts = new Dictionary<string, string>(); |
||||
|
var allTexts = await TextRepository.GetListAsync(cacheItem.ResourceName, cacheItem.CultureName); |
||||
|
foreach (var text in allTexts) |
||||
|
{ |
||||
|
setTexts[text.Key] = text.Value; |
||||
|
} |
||||
|
|
||||
|
var textCacheKey = LocalizationTextCacheItem.CalculateCacheKey(cacheItem.ResourceName, cacheItem.CultureName); |
||||
|
var textCacheItem = new LocalizationTextCacheItem(cacheItem.ResourceName, cacheItem.CultureName, setTexts); |
||||
|
|
||||
|
await LocalizationTextCache.SetAsync(textCacheKey, textCacheItem); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,36 +0,0 @@ |
|||||
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); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,21 +0,0 @@ |
|||||
using System.Threading.Tasks; |
|
||||
using Volo.Abp.Caching; |
|
||||
using Volo.Abp.DependencyInjection; |
|
||||
using Volo.Abp.Domain.Entities.Events; |
|
||||
using Volo.Abp.EventBus; |
|
||||
|
|
||||
namespace LINGYUN.Abp.LocalizationManagement; |
|
||||
|
|
||||
public class LocalizationLanguageCacheInvalidator: ILocalEventHandler<EntityChangedEventData<Language>>, ITransientDependency |
|
||||
{ |
|
||||
private readonly IDistributedCache<LocalizationLanguageCacheItem> _localizationLanguageCache; |
|
||||
public LocalizationLanguageCacheInvalidator(IDistributedCache<LocalizationLanguageCacheItem> localizationLanguageCache) |
|
||||
{ |
|
||||
_localizationLanguageCache = localizationLanguageCache; |
|
||||
} |
|
||||
|
|
||||
public async virtual Task HandleEventAsync(EntityChangedEventData<Language> eventData) |
|
||||
{ |
|
||||
await _localizationLanguageCache.RemoveAsync(LocalizationLanguageCacheItem.CacheKey); |
|
||||
} |
|
||||
} |
|
||||
@ -1,32 +0,0 @@ |
|||||
using LINGYUN.Abp.LocalizationManagement.External; |
|
||||
using System.Threading.Tasks; |
|
||||
using Volo.Abp.Caching; |
|
||||
using Volo.Abp.DependencyInjection; |
|
||||
using Volo.Abp.Domain.Entities.Events; |
|
||||
using Volo.Abp.EventBus; |
|
||||
|
|
||||
namespace LINGYUN.Abp.LocalizationManagement; |
|
||||
|
|
||||
public class LocalizationTextCacheInvalidator : ILocalEventHandler<EntityChangedEventData<Text>>, ITransientDependency |
|
||||
{ |
|
||||
private readonly IDistributedCache<LocalizationTextCacheItem> _localizationTextCache; |
|
||||
private readonly IExternalLocalizationTextStoreCache _externalLocalizationTextStoreCache; |
|
||||
public LocalizationTextCacheInvalidator( |
|
||||
IDistributedCache<LocalizationTextCacheItem> localizationTextCache, |
|
||||
IExternalLocalizationTextStoreCache externalLocalizationTextStoreCache) |
|
||||
{ |
|
||||
_externalLocalizationTextStoreCache = externalLocalizationTextStoreCache; |
|
||||
_localizationTextCache = localizationTextCache; |
|
||||
} |
|
||||
|
|
||||
public async virtual Task HandleEventAsync(EntityChangedEventData<Text> eventData) |
|
||||
{ |
|
||||
var cacheKey = LocalizationTextCacheItem.CalculateCacheKey( |
|
||||
eventData.Entity.ResourceName, |
|
||||
eventData.Entity.CultureName); |
|
||||
|
|
||||
await _localizationTextCache.RemoveAsync(cacheKey); |
|
||||
|
|
||||
await _externalLocalizationTextStoreCache.RemoveAsync(eventData.Entity.ResourceName, eventData.Entity.CultureName); |
|
||||
} |
|
||||
} |
|
||||
Loading…
Reference in new issue