From c4f2ba392c51d073f4764fad9efd9e05a88af1c9 Mon Sep 17 00:00:00 2001 From: cKey <35512826+colinin@users.noreply.github.com> Date: Mon, 18 Jul 2022 20:08:29 +0800 Subject: [PATCH] add template content to the cache --- .../Mvc/Localization/LanguageAppService.cs | 2 +- .../Mvc/Localization/ResourceAppService.cs | 2 +- .../Mvc/Localization/TextAppService.cs | 12 +++-- .../Mvc/Localization/TextDifferenceDto.cs | 7 ++- .../LINGYUN.Abp.TextTemplating.Domain.csproj | 1 + .../AbpTextTemplatingCachingOptions.cs | 21 ++++++++ .../AbpTextTemplatingDomainModule.cs | 6 ++- .../TemplateContentCacheItem.cs | 34 ++++++++++++ .../TextTemplateCacheItemInvalidator.cs | 52 +++++++++++++++++++ .../TextTemplateContentContributor.cs | 41 ++++++++++++++- ...entityServerHttpApiHostModule.Configure.cs | 2 +- .../appsettings.Development.json | 2 +- .../IdentityServerModule.Configure.cs | 2 +- .../appsettings.Development.json | 2 +- 14 files changed, 171 insertions(+), 15 deletions(-) create mode 100644 aspnet-core/modules/text-templating/LINGYUN.Abp.TextTemplating.Domain/LINGYUN/Abp/TextTemplating/AbpTextTemplatingCachingOptions.cs create mode 100644 aspnet-core/modules/text-templating/LINGYUN.Abp.TextTemplating.Domain/LINGYUN/Abp/TextTemplating/TemplateContentCacheItem.cs create mode 100644 aspnet-core/modules/text-templating/LINGYUN.Abp.TextTemplating.Domain/LINGYUN/Abp/TextTemplating/TextTemplateCacheItemInvalidator.cs diff --git a/aspnet-core/modules/localization/LINGYUN.Abp.AspNetCore.Mvc.Localization/LINGYUN/Abp/AspNetCore/Mvc/Localization/LanguageAppService.cs b/aspnet-core/modules/localization/LINGYUN.Abp.AspNetCore.Mvc.Localization/LINGYUN/Abp/AspNetCore/Mvc/Localization/LanguageAppService.cs index 77b191e10..7cd6ff4b2 100644 --- a/aspnet-core/modules/localization/LINGYUN.Abp.AspNetCore.Mvc.Localization/LINGYUN/Abp/AspNetCore/Mvc/Localization/LanguageAppService.cs +++ b/aspnet-core/modules/localization/LINGYUN.Abp.AspNetCore.Mvc.Localization/LINGYUN/Abp/AspNetCore/Mvc/Localization/LanguageAppService.cs @@ -27,7 +27,7 @@ namespace LINGYUN.Abp.AspNetCore.Mvc.Localization UiCultureName = l.UiCultureName, DisplayName = l.DisplayName, FlagIcon = l.FlagIcon - }).ToList()); + }).OrderBy(l => l.CultureName).ToList()); } } } diff --git a/aspnet-core/modules/localization/LINGYUN.Abp.AspNetCore.Mvc.Localization/LINGYUN/Abp/AspNetCore/Mvc/Localization/ResourceAppService.cs b/aspnet-core/modules/localization/LINGYUN.Abp.AspNetCore.Mvc.Localization/LINGYUN/Abp/AspNetCore/Mvc/Localization/ResourceAppService.cs index fb87bcafa..829b34ce9 100644 --- a/aspnet-core/modules/localization/LINGYUN.Abp.AspNetCore.Mvc.Localization/LINGYUN/Abp/AspNetCore/Mvc/Localization/ResourceAppService.cs +++ b/aspnet-core/modules/localization/LINGYUN.Abp.AspNetCore.Mvc.Localization/LINGYUN/Abp/AspNetCore/Mvc/Localization/ResourceAppService.cs @@ -26,7 +26,7 @@ namespace LINGYUN.Abp.AspNetCore.Mvc.Localization Name = x.Value.ResourceName, DisplayName = x.Value.ResourceName, Description = x.Value.ResourceName, - }); + }).OrderBy(l => l.Name); return Task.FromResult(new ListResultDto(resources.ToList())); } diff --git a/aspnet-core/modules/localization/LINGYUN.Abp.AspNetCore.Mvc.Localization/LINGYUN/Abp/AspNetCore/Mvc/Localization/TextAppService.cs b/aspnet-core/modules/localization/LINGYUN.Abp.AspNetCore.Mvc.Localization/LINGYUN/Abp/AspNetCore/Mvc/Localization/TextAppService.cs index 5bdcc0dfe..fea4c1d2e 100644 --- a/aspnet-core/modules/localization/LINGYUN.Abp.AspNetCore.Mvc.Localization/LINGYUN/Abp/AspNetCore/Mvc/Localization/TextAppService.cs +++ b/aspnet-core/modules/localization/LINGYUN.Abp.AspNetCore.Mvc.Localization/LINGYUN/Abp/AspNetCore/Mvc/Localization/TextAppService.cs @@ -36,7 +36,8 @@ namespace LINGYUN.Abp.AspNetCore.Mvc.Localization using (CultureHelper.Use(input.CultureName)) { - localizedStrings = localizer.GetAllStrings(true); + localizedStrings = localizer.GetAllStrings(true) + .OrderBy(l => l.Name); var result = new TextDto { @@ -57,7 +58,8 @@ namespace LINGYUN.Abp.AspNetCore.Mvc.Localization if (input.ResourceName.IsNullOrWhiteSpace()) { var filterResources = _localizationOptions.Resources - .WhereIf(!input.Filter.IsNullOrWhiteSpace(), x => x.Value.ResourceName.Contains(input.Filter)); + .WhereIf(!input.Filter.IsNullOrWhiteSpace(), x => x.Value.ResourceName.Contains(input.Filter)) + .OrderBy(r => r.Value.ResourceName); foreach (var resource in filterResources) { @@ -96,7 +98,8 @@ namespace LINGYUN.Abp.AspNetCore.Mvc.Localization using (CultureHelper.Use(cultureName)) { localizedStrings = localizer.GetAllStrings(true) - .WhereIf(!filter.IsNullOrWhiteSpace(), x => x.Name.Contains(filter)); + .WhereIf(!filter.IsNullOrWhiteSpace(), x => x.Name.Contains(filter)) + .OrderBy(l => l.Name); } if (Equals(cultureName, targetCultureName)) @@ -108,7 +111,8 @@ namespace LINGYUN.Abp.AspNetCore.Mvc.Localization using (CultureHelper.Use(targetCultureName)) { targetLocalizedStrings = localizer.GetAllStrings(true) - .WhereIf(!filter.IsNullOrWhiteSpace(), x => x.Name.Contains(filter)); + .WhereIf(!filter.IsNullOrWhiteSpace(), x => x.Name.Contains(filter)) + .OrderBy(l => l.Name); } } diff --git a/aspnet-core/modules/localization/LINGYUN.Abp.AspNetCore.Mvc.Localization/LINGYUN/Abp/AspNetCore/Mvc/Localization/TextDifferenceDto.cs b/aspnet-core/modules/localization/LINGYUN.Abp.AspNetCore.Mvc.Localization/LINGYUN/Abp/AspNetCore/Mvc/Localization/TextDifferenceDto.cs index 9675e7581..fbf6819b5 100644 --- a/aspnet-core/modules/localization/LINGYUN.Abp.AspNetCore.Mvc.Localization/LINGYUN/Abp/AspNetCore/Mvc/Localization/TextDifferenceDto.cs +++ b/aspnet-core/modules/localization/LINGYUN.Abp.AspNetCore.Mvc.Localization/LINGYUN/Abp/AspNetCore/Mvc/Localization/TextDifferenceDto.cs @@ -7,6 +7,11 @@ public string Value { get; set; } public string ResourceName { get; set; } public string TargetCultureName { get; set; } - public string TargetValue { get; set; } + public string TargetValue { get; set; } + + public int CompareTo(TextDifferenceDto other) + { + return other.ResourceName.CompareTo(ResourceName) ^ other.Key.CompareTo(Key); + } } } diff --git a/aspnet-core/modules/text-templating/LINGYUN.Abp.TextTemplating.Domain/LINGYUN.Abp.TextTemplating.Domain.csproj b/aspnet-core/modules/text-templating/LINGYUN.Abp.TextTemplating.Domain/LINGYUN.Abp.TextTemplating.Domain.csproj index fc31bc931..e05b8a0bb 100644 --- a/aspnet-core/modules/text-templating/LINGYUN.Abp.TextTemplating.Domain/LINGYUN.Abp.TextTemplating.Domain.csproj +++ b/aspnet-core/modules/text-templating/LINGYUN.Abp.TextTemplating.Domain/LINGYUN.Abp.TextTemplating.Domain.csproj @@ -9,6 +9,7 @@ + diff --git a/aspnet-core/modules/text-templating/LINGYUN.Abp.TextTemplating.Domain/LINGYUN/Abp/TextTemplating/AbpTextTemplatingCachingOptions.cs b/aspnet-core/modules/text-templating/LINGYUN.Abp.TextTemplating.Domain/LINGYUN/Abp/TextTemplating/AbpTextTemplatingCachingOptions.cs new file mode 100644 index 000000000..02470854f --- /dev/null +++ b/aspnet-core/modules/text-templating/LINGYUN.Abp.TextTemplating.Domain/LINGYUN/Abp/TextTemplating/AbpTextTemplatingCachingOptions.cs @@ -0,0 +1,21 @@ +using System; + +namespace LINGYUN.Abp.TextTemplating; + +public class AbpTextTemplatingCachingOptions +{ + /// + /// 文本模板缓存最小过期时间 + /// + public TimeSpan? MinimumCacheDuration { get; set; } + /// + /// 文本模板缓存绝对过期时间 + /// + public TimeSpan? MaximumCacheDuration { get; set; } + + public AbpTextTemplatingCachingOptions() + { + MinimumCacheDuration = TimeSpan.FromHours(1); + MaximumCacheDuration = TimeSpan.FromDays(30); + } +} diff --git a/aspnet-core/modules/text-templating/LINGYUN.Abp.TextTemplating.Domain/LINGYUN/Abp/TextTemplating/AbpTextTemplatingDomainModule.cs b/aspnet-core/modules/text-templating/LINGYUN.Abp.TextTemplating.Domain/LINGYUN/Abp/TextTemplating/AbpTextTemplatingDomainModule.cs index 0bba602d8..8ea529d21 100644 --- a/aspnet-core/modules/text-templating/LINGYUN.Abp.TextTemplating.Domain/LINGYUN/Abp/TextTemplating/AbpTextTemplatingDomainModule.cs +++ b/aspnet-core/modules/text-templating/LINGYUN.Abp.TextTemplating.Domain/LINGYUN/Abp/TextTemplating/AbpTextTemplatingDomainModule.cs @@ -1,11 +1,13 @@ -using Volo.Abp.Modularity; +using Volo.Abp.Caching; +using Volo.Abp.Modularity; using Volo.Abp.TextTemplating; namespace LINGYUN.Abp.TextTemplating; [DependsOn( typeof(AbpTextTemplatingDomainSharedModule), - typeof(AbpTextTemplatingCoreModule))] + typeof(AbpTextTemplatingCoreModule), + typeof(AbpCachingModule))] public class AbpTextTemplatingDomainModule : AbpModule { diff --git a/aspnet-core/modules/text-templating/LINGYUN.Abp.TextTemplating.Domain/LINGYUN/Abp/TextTemplating/TemplateContentCacheItem.cs b/aspnet-core/modules/text-templating/LINGYUN.Abp.TextTemplating.Domain/LINGYUN/Abp/TextTemplating/TemplateContentCacheItem.cs new file mode 100644 index 000000000..58a3c51ef --- /dev/null +++ b/aspnet-core/modules/text-templating/LINGYUN.Abp.TextTemplating.Domain/LINGYUN/Abp/TextTemplating/TemplateContentCacheItem.cs @@ -0,0 +1,34 @@ +namespace LINGYUN.Abp.TextTemplating; + +public class TemplateContentCacheItem +{ + private const string CacheKeyFormat = "pn:template-content,n:{0},c:{1}"; + + public string Name { get; set; } + public string Culture { get; set; } + public string Content { get; set; } + public TemplateContentCacheItem() + { + + } + + public TemplateContentCacheItem( + string name, + string content, + string culture = null) + { + Name = name; + Content = content; + Culture = culture; + } + + public static string CalculateCacheKey( + string name, + string culture = null) + { + return string.Format( + CacheKeyFormat, + name, + culture); + } +} diff --git a/aspnet-core/modules/text-templating/LINGYUN.Abp.TextTemplating.Domain/LINGYUN/Abp/TextTemplating/TextTemplateCacheItemInvalidator.cs b/aspnet-core/modules/text-templating/LINGYUN.Abp.TextTemplating.Domain/LINGYUN/Abp/TextTemplating/TextTemplateCacheItemInvalidator.cs new file mode 100644 index 000000000..6571ce068 --- /dev/null +++ b/aspnet-core/modules/text-templating/LINGYUN.Abp.TextTemplating.Domain/LINGYUN/Abp/TextTemplating/TextTemplateCacheItemInvalidator.cs @@ -0,0 +1,52 @@ +using System.Threading.Tasks; +using Volo.Abp.Caching; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Domain.Entities.Events; +using Volo.Abp.EventBus; +using Volo.Abp.MultiTenancy; + +namespace LINGYUN.Abp.TextTemplating; + +public class TextTemplateCacheItemInvalidator : + ILocalEventHandler>, + ILocalEventHandler>, + ITransientDependency +{ + protected ICurrentTenant CurrentTenant { get; } + + protected IDistributedCache Cache { get; } + + public TextTemplateCacheItemInvalidator(IDistributedCache cache, ICurrentTenant currentTenant) + { + Cache = cache; + CurrentTenant = currentTenant; + } + + public async virtual Task HandleEventAsync(EntityChangedEventData eventData) + { + await RemoveCacheItemAsync(eventData.Entity); + } + + public async virtual Task HandleEventAsync(EntityDeletedEventData eventData) + { + await RemoveCacheItemAsync(eventData.Entity); + } + + protected async virtual Task RemoveCacheItemAsync(TextTemplate template) + { + var cacheKey = CalculateCacheKey( + template.Name, + template.Culture + ); + + using (CurrentTenant.Change(template.TenantId)) + { + await Cache.RemoveAsync(cacheKey); + } + } + + protected virtual string CalculateCacheKey(string name, string culture = null) + { + return TemplateContentCacheItem.CalculateCacheKey(name, culture); + } +} diff --git a/aspnet-core/modules/text-templating/LINGYUN.Abp.TextTemplating.Domain/LINGYUN/Abp/TextTemplating/TextTemplateContentContributor.cs b/aspnet-core/modules/text-templating/LINGYUN.Abp.TextTemplating.Domain/LINGYUN/Abp/TextTemplating/TextTemplateContentContributor.cs index 0fd44ce09..06699fbe7 100644 --- a/aspnet-core/modules/text-templating/LINGYUN.Abp.TextTemplating.Domain/LINGYUN/Abp/TextTemplating/TextTemplateContentContributor.cs +++ b/aspnet-core/modules/text-templating/LINGYUN.Abp.TextTemplating.Domain/LINGYUN/Abp/TextTemplating/TextTemplateContentContributor.cs @@ -1,5 +1,8 @@ -using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Caching.Distributed; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using System.Threading.Tasks; +using Volo.Abp.Caching; using Volo.Abp.DependencyInjection; using Volo.Abp.TextTemplating; @@ -7,11 +10,45 @@ namespace LINGYUN.Abp.TextTemplating; public class TextTemplateContentContributor : ITemplateContentContributor, ITransientDependency { + protected AbpTextTemplatingCachingOptions TemplatingCachingOptions { get; } + protected IDistributedCache TextTemplateContentCache { get; } + + public TextTemplateContentContributor( + IDistributedCache textTemplateContentCache, + IOptions templatingCachingOptions) + { + TextTemplateContentCache = textTemplateContentCache; + TemplatingCachingOptions = templatingCachingOptions.Value; + } + public async virtual Task GetOrNullAsync(TemplateContentContributorContext context) + { + var cacheKey = TemplateContentCacheItem.CalculateCacheKey(context.TemplateDefinition.Name, context.Culture); + + var cacheItem = await TextTemplateContentCache.GetOrAddAsync(cacheKey, + () => CreateTemplateContentCache(context), + () => CreateTemplateContentCacheOptions()); + + return cacheItem?.Content; + } + + protected async virtual Task CreateTemplateContentCache(TemplateContentContributorContext context) { var repository = context.ServiceProvider.GetRequiredService(); var template = await repository.FindByNameAsync(context.TemplateDefinition.Name, context.Culture); - return template?.Content; + return new TemplateContentCacheItem( + template?.Name, + template?.Content, + template?.Culture); + } + + protected DistributedCacheEntryOptions CreateTemplateContentCacheOptions() + { + return new DistributedCacheEntryOptions + { + SlidingExpiration = TemplatingCachingOptions.MinimumCacheDuration, + AbsoluteExpirationRelativeToNow = TemplatingCachingOptions.MaximumCacheDuration, + }; } } diff --git a/aspnet-core/services/LY.MicroService.identityServer.HttpApi.Host/IdentityServerHttpApiHostModule.Configure.cs b/aspnet-core/services/LY.MicroService.identityServer.HttpApi.Host/IdentityServerHttpApiHostModule.Configure.cs index 5ce526edf..aba44dc51 100644 --- a/aspnet-core/services/LY.MicroService.identityServer.HttpApi.Host/IdentityServerHttpApiHostModule.Configure.cs +++ b/aspnet-core/services/LY.MicroService.identityServer.HttpApi.Host/IdentityServerHttpApiHostModule.Configure.cs @@ -166,7 +166,7 @@ public partial class IdentityServerHttpApiHostModule Configure(options => { options.Applications["MVC"].RootUrl = configuration["App:SelfUrl"]; - options.Applications["VUE"].RootUrl = configuration["App:VueUrl"]; + options.Applications["STS"].RootUrl = configuration["App:StsUrl"]; }); } diff --git a/aspnet-core/services/LY.MicroService.identityServer.HttpApi.Host/appsettings.Development.json b/aspnet-core/services/LY.MicroService.identityServer.HttpApi.Host/appsettings.Development.json index 5925874b6..40f404a1e 100644 --- a/aspnet-core/services/LY.MicroService.identityServer.HttpApi.Host/appsettings.Development.json +++ b/aspnet-core/services/LY.MicroService.identityServer.HttpApi.Host/appsettings.Development.json @@ -10,7 +10,7 @@ "App": { "TrackingEntitiesChanged": true, "SelfUrl": "http://127.0.0.1:30015/", - "VueUrl": "http://127.0.0.1:3100/", + "StsUrl": "http://127.0.0.1:44385/", "CorsOrigins": "http://127.0.0.1:3100" }, "ConnectionStrings": { diff --git a/aspnet-core/services/LY.MicroService.identityServer/IdentityServerModule.Configure.cs b/aspnet-core/services/LY.MicroService.identityServer/IdentityServerModule.Configure.cs index 0b6814cd5..0b6f27f04 100644 --- a/aspnet-core/services/LY.MicroService.identityServer/IdentityServerModule.Configure.cs +++ b/aspnet-core/services/LY.MicroService.identityServer/IdentityServerModule.Configure.cs @@ -207,7 +207,7 @@ public partial class IdentityServerModule Configure(options => { options.Applications["MVC"].RootUrl = configuration["App:SelfUrl"]; - options.Applications["VUE"].RootUrl = configuration["App:VueUrl"]; + options.Applications["STS"].RootUrl = configuration["App:StsUrl"]; options.Applications["MVC"].Urls["EmailVerifyLogin"] = "Account/VerifyCode"; options.Applications["MVC"].Urls["EmailConfirm"] = "Account/EmailConfirm"; diff --git a/aspnet-core/services/LY.MicroService.identityServer/appsettings.Development.json b/aspnet-core/services/LY.MicroService.identityServer/appsettings.Development.json index d9959f072..e436fc3c8 100644 --- a/aspnet-core/services/LY.MicroService.identityServer/appsettings.Development.json +++ b/aspnet-core/services/LY.MicroService.identityServer/appsettings.Development.json @@ -10,7 +10,7 @@ "App": { "TrackingEntitiesChanged": true, "SelfUrl": "http://127.0.0.1:44385/", - "VueUrl": "http://127.0.0.1:3100/", + "StsUrl": "http://127.0.0.1:44385/", "CorsOrigins": "http://127.0.0.1:3100" }, "AppSelfUrl": "http://127.0.0.1:44385/",