From 14d1bbc87790abeef88263ca64c4c4ec8d321251 Mon Sep 17 00:00:00 2001 From: maliming Date: Mon, 28 Nov 2022 13:29:02 +0800 Subject: [PATCH] Introduce `IAbpHostEnvironment` and reduce cache durations for development environment Resolve #13952 --- .../AbpWebAssemblyHostBuilderExtensions.cs | 8 ++++ .../AbpAspNetCoreMvcClientCacheOptions.cs | 16 ++++++++ .../Client/AbpAspNetCoreMvcClientModule.cs | 15 +++++++- ...MvcCachedApplicationConfigurationClient.cs | 14 ++++--- .../Mvc/Client/MvcRemoteTenantStore.cs | 26 ++++++------- .../WebApplicationBuilderExtensions.cs | 12 +++++- .../ServiceCollectionApplicationExtensions.cs | 10 ++++- .../Volo/Abp/AbpApplicationBase.cs | 7 ++++ .../Volo/Abp/AbpApplicationCreationOptions.cs | 5 ++- .../Volo/Abp/AbpHostEnvironment.cs | 6 +++ .../Volo/Abp/AbpHostEnvironmentExtensions.cs | 38 +++++++++++++++++++ .../Volo/Abp/IAbpHostEnvironment.cs | 6 +++ .../IdentityModelAuthenticationService.cs | 20 ++++++---- 13 files changed, 152 insertions(+), 31 deletions(-) create mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/AbpAspNetCoreMvcClientCacheOptions.cs create mode 100644 framework/src/Volo.Abp.Core/Volo/Abp/AbpHostEnvironment.cs create mode 100644 framework/src/Volo.Abp.Core/Volo/Abp/AbpHostEnvironmentExtensions.cs create mode 100644 framework/src/Volo.Abp.Core/Volo/Abp/IAbpHostEnvironment.cs diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Microsoft/AspNetCore/Components/WebAssembly/Hosting/AbpWebAssemblyHostBuilderExtensions.cs b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Microsoft/AspNetCore/Components/WebAssembly/Hosting/AbpWebAssemblyHostBuilderExtensions.cs index 21f29f995c..36ca9b4b55 100644 --- a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Microsoft/AspNetCore/Components/WebAssembly/Hosting/AbpWebAssemblyHostBuilderExtensions.cs +++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Microsoft/AspNetCore/Components/WebAssembly/Hosting/AbpWebAssemblyHostBuilderExtensions.cs @@ -33,6 +33,10 @@ public static class AbpWebAssemblyHostBuilderExtensions var application = await builder.Services.AddApplicationAsync(opts => { options?.Invoke(new AbpWebAssemblyApplicationCreationOptions(builder, opts)); + if (opts.Environment.IsNullOrWhiteSpace()) + { + opts.Environment = builder.HostEnvironment.Environment; + } }); return application; @@ -57,6 +61,10 @@ public static class AbpWebAssemblyHostBuilderExtensions var application = builder.Services.AddApplication(opts => { options?.Invoke(new AbpWebAssemblyApplicationCreationOptions(builder, opts)); + if (opts.Environment.IsNullOrWhiteSpace()) + { + opts.Environment = builder.HostEnvironment.Environment; + } }); return application; diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/AbpAspNetCoreMvcClientCacheOptions.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/AbpAspNetCoreMvcClientCacheOptions.cs new file mode 100644 index 0000000000..902f7932ab --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/AbpAspNetCoreMvcClientCacheOptions.cs @@ -0,0 +1,16 @@ +using System; + +namespace Volo.Abp.AspNetCore.Mvc.Client; + +public class AbpAspNetCoreMvcClientCacheOptions +{ + public TimeSpan TenantConfigurationCacheAbsoluteExpiration { get; set; } + + public TimeSpan ApplicationConfigurationDtoCacheAbsoluteExpiration { get; set; } + + public AbpAspNetCoreMvcClientCacheOptions() + { + TenantConfigurationCacheAbsoluteExpiration = TimeSpan.FromMinutes(5); + TenantConfigurationCacheAbsoluteExpiration = TimeSpan.FromSeconds(300); + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/AbpAspNetCoreMvcClientModule.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/AbpAspNetCoreMvcClientModule.cs index ae5421d947..4a7e8b6cb4 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/AbpAspNetCoreMvcClientModule.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/AbpAspNetCoreMvcClientModule.cs @@ -1,3 +1,5 @@ +using System; +using Microsoft.Extensions.DependencyInjection; using Volo.Abp.EventBus; using Volo.Abp.Modularity; @@ -9,5 +11,16 @@ namespace Volo.Abp.AspNetCore.Mvc.Client; )] public class AbpAspNetCoreMvcClientModule : AbpModule { - + public override void ConfigureServices(ServiceConfigurationContext context) + { + var abpHostEnvironment = context.Services.GetAbpHostEnvironment(); + if (abpHostEnvironment.IsDevelopment()) + { + Configure(options => + { + options.TenantConfigurationCacheAbsoluteExpiration = TimeSpan.Zero; + options.ApplicationConfigurationDtoCacheAbsoluteExpiration = TimeSpan.Zero; + }); + } + } } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcCachedApplicationConfigurationClient.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcCachedApplicationConfigurationClient.cs index 405d43906d..6f2cc1a05f 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcCachedApplicationConfigurationClient.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcCachedApplicationConfigurationClient.cs @@ -2,6 +2,7 @@ using System; using Microsoft.AspNetCore.Http; using System.Threading.Tasks; using Microsoft.Extensions.Caching.Distributed; +using Microsoft.Extensions.Options; using Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations; using Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ClientProxies; using Volo.Abp.Caching; @@ -18,18 +19,21 @@ public class MvcCachedApplicationConfigurationClient : ICachedApplicationConfigu protected AbpApplicationLocalizationClientProxy ApplicationLocalizationClientProxy { get; } protected ICurrentUser CurrentUser { get; } protected IDistributedCache Cache { get; } + protected AbpAspNetCoreMvcClientCacheOptions Options { get; } public MvcCachedApplicationConfigurationClient( IDistributedCache cache, AbpApplicationConfigurationClientProxy applicationConfigurationAppService, ICurrentUser currentUser, - IHttpContextAccessor httpContextAccessor, - AbpApplicationLocalizationClientProxy applicationLocalizationClientProxy) + IHttpContextAccessor httpContextAccessor, + AbpApplicationLocalizationClientProxy applicationLocalizationClientProxy, + IOptions options) { ApplicationConfigurationAppService = applicationConfigurationAppService; CurrentUser = currentUser; HttpContextAccessor = httpContextAccessor; ApplicationLocalizationClientProxy = applicationLocalizationClientProxy; + Options = options.Value; Cache = cache; } @@ -48,7 +52,7 @@ public class MvcCachedApplicationConfigurationClient : ICachedApplicationConfigu async () => await GetRemoteConfigurationAsync(), () => new DistributedCacheEntryOptions { - AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(300) //TODO: Should be configurable. + AbsoluteExpirationRelativeToNow = Options.ApplicationConfigurationDtoCacheAbsoluteExpiration } ); @@ -68,7 +72,7 @@ public class MvcCachedApplicationConfigurationClient : ICachedApplicationConfigu IncludeLocalizationResources = false } ); - + var localizationDto = await ApplicationLocalizationClientProxy.GetAsync( new ApplicationLocalizationRequestDto { CultureName = config.Localization.CurrentCulture.Name, @@ -77,7 +81,7 @@ public class MvcCachedApplicationConfigurationClient : ICachedApplicationConfigu ); config.Localization.Resources = localizationDto.Resources; - + return config; } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcRemoteTenantStore.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcRemoteTenantStore.cs index dd4411255e..3f091f8db8 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcRemoteTenantStore.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcRemoteTenantStore.cs @@ -2,6 +2,7 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Caching.Distributed; +using Microsoft.Extensions.Options; using Pages.Abp.MultiTenancy.ClientProxies; using Volo.Abp.AspNetCore.Mvc.MultiTenancy; using Volo.Abp.Caching; @@ -16,15 +17,18 @@ public class MvcRemoteTenantStore : ITenantStore, ITransientDependency protected AbpTenantClientProxy TenantAppService { get; } protected IHttpContextAccessor HttpContextAccessor { get; } protected IDistributedCache Cache { get; } + protected AbpAspNetCoreMvcClientCacheOptions Options { get; } public MvcRemoteTenantStore( AbpTenantClientProxy tenantAppService, IHttpContextAccessor httpContextAccessor, - IDistributedCache cache) + IDistributedCache cache, + IOptions options) { TenantAppService = tenantAppService; HttpContextAccessor = httpContextAccessor; Cache = cache; + Options = options.Value; } public async Task FindAsync(string name) @@ -42,9 +46,8 @@ public class MvcRemoteTenantStore : ITenantStore, ITransientDependency async () => CreateTenantConfiguration(await TenantAppService.FindTenantByNameAsync(name)), () => new DistributedCacheEntryOptions { - AbsoluteExpirationRelativeToNow = - TimeSpan.FromMinutes(5) //TODO: Should be configurable. - } + AbsoluteExpirationRelativeToNow = Options.TenantConfigurationCacheAbsoluteExpiration + } ); if (httpContext != null) @@ -70,9 +73,8 @@ public class MvcRemoteTenantStore : ITenantStore, ITransientDependency async () => CreateTenantConfiguration(await TenantAppService.FindTenantByIdAsync(id)), () => new DistributedCacheEntryOptions { - AbsoluteExpirationRelativeToNow = - TimeSpan.FromMinutes(5) //TODO: Should be configurable. - } + AbsoluteExpirationRelativeToNow = Options.TenantConfigurationCacheAbsoluteExpiration + } ); if (httpContext != null) @@ -98,9 +100,8 @@ public class MvcRemoteTenantStore : ITenantStore, ITransientDependency () => AsyncHelper.RunSync(async () => CreateTenantConfiguration(await TenantAppService.FindTenantByNameAsync(name))), () => new DistributedCacheEntryOptions { - AbsoluteExpirationRelativeToNow = - TimeSpan.FromMinutes(5) //TODO: Should be configurable. - } + AbsoluteExpirationRelativeToNow = Options.TenantConfigurationCacheAbsoluteExpiration + } ); if (httpContext != null) @@ -126,9 +127,8 @@ public class MvcRemoteTenantStore : ITenantStore, ITransientDependency () => AsyncHelper.RunSync(async () => CreateTenantConfiguration(await TenantAppService.FindTenantByIdAsync(id))), () => new DistributedCacheEntryOptions { - AbsoluteExpirationRelativeToNow = - TimeSpan.FromMinutes(5) //TODO: Should be configurable. - } + AbsoluteExpirationRelativeToNow = Options.TenantConfigurationCacheAbsoluteExpiration + } ); if (httpContext != null) diff --git a/framework/src/Volo.Abp.AspNetCore/Microsoft/Extensions/DependencyInjection/WebApplicationBuilderExtensions.cs b/framework/src/Volo.Abp.AspNetCore/Microsoft/Extensions/DependencyInjection/WebApplicationBuilderExtensions.cs index 692825520b..f044348052 100644 --- a/framework/src/Volo.Abp.AspNetCore/Microsoft/Extensions/DependencyInjection/WebApplicationBuilderExtensions.cs +++ b/framework/src/Volo.Abp.AspNetCore/Microsoft/Extensions/DependencyInjection/WebApplicationBuilderExtensions.cs @@ -9,7 +9,7 @@ namespace Microsoft.Extensions.DependencyInjection; public static class WebApplicationBuilderExtensions { - public async static Task AddApplicationAsync( + public static async Task AddApplicationAsync( [NotNull] this WebApplicationBuilder builder, [CanBeNull] Action optionsAction = null) where TStartupModule : IAbpModule @@ -18,10 +18,14 @@ public static class WebApplicationBuilderExtensions { options.Services.ReplaceConfiguration(builder.Configuration); optionsAction?.Invoke(options); + if (options.Environment.IsNullOrWhiteSpace()) + { + options.Environment = builder.Environment.EnvironmentName; + } }); } - public async static Task AddApplicationAsync( + public static async Task AddApplicationAsync( [NotNull] this WebApplicationBuilder builder, [NotNull] Type startupModuleType, [CanBeNull] Action optionsAction = null) @@ -30,6 +34,10 @@ public static class WebApplicationBuilderExtensions { options.Services.ReplaceConfiguration(builder.Configuration); optionsAction?.Invoke(options); + if (options.Environment.IsNullOrWhiteSpace()) + { + options.Environment = builder.Environment.EnvironmentName; + } }); } } diff --git a/framework/src/Volo.Abp.Core/Microsoft/Extensions/DependencyInjection/ServiceCollectionApplicationExtensions.cs b/framework/src/Volo.Abp.Core/Microsoft/Extensions/DependencyInjection/ServiceCollectionApplicationExtensions.cs index 278814780d..3ad02c7f1d 100644 --- a/framework/src/Volo.Abp.Core/Microsoft/Extensions/DependencyInjection/ServiceCollectionApplicationExtensions.cs +++ b/framework/src/Volo.Abp.Core/Microsoft/Extensions/DependencyInjection/ServiceCollectionApplicationExtensions.cs @@ -39,16 +39,22 @@ public static class ServiceCollectionApplicationExtensions { return await AbpApplicationFactory.CreateAsync(startupModuleType, services, optionsAction); } - + [CanBeNull] public static string GetApplicationName(this IServiceCollection services) { return services.GetSingletonInstance().ApplicationName; } - + [NotNull] public static string GetApplicationInstanceId(this IServiceCollection services) { return services.GetSingletonInstance().InstanceId; } + + [NotNull] + public static IAbpHostEnvironment GetAbpHostEnvironment(this IServiceCollection services) + { + return services.GetSingletonInstance(); + } } diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationBase.cs b/framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationBase.cs index fd91b09982..f9fd7676a7 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationBase.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationBase.cs @@ -5,6 +5,7 @@ using System.Reflection; using System.Threading.Tasks; using JetBrains.Annotations; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using Volo.Abp.DependencyInjection; using Volo.Abp.Internal; @@ -51,6 +52,12 @@ public abstract class AbpApplicationBase : IAbpApplication services.AddSingleton(this); services.AddSingleton(this); services.AddSingleton(this); + services.AddSingleton(new AbpHostEnvironment() + { + EnvironmentName = options.Environment.IsNullOrWhiteSpace() + ? Environments.Production + : options.Environment + }); services.AddCoreServices(); services.AddCoreAbpServices(this, options); diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationCreationOptions.cs b/framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationCreationOptions.cs index 24a1bf8ee6..e1f7f4c997 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationCreationOptions.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationCreationOptions.cs @@ -20,10 +20,13 @@ public class AbpApplicationCreationOptions public AbpConfigurationBuilderOptions Configuration { get; } public bool SkipConfigureServices { get; set; } - + [CanBeNull] public string ApplicationName { get; set; } + [CanBeNull] + public string Environment { get; set; } + public AbpApplicationCreationOptions([NotNull] IServiceCollection services) { Services = Check.NotNull(services, nameof(services)); diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/AbpHostEnvironment.cs b/framework/src/Volo.Abp.Core/Volo/Abp/AbpHostEnvironment.cs new file mode 100644 index 0000000000..a2682909a1 --- /dev/null +++ b/framework/src/Volo.Abp.Core/Volo/Abp/AbpHostEnvironment.cs @@ -0,0 +1,6 @@ +namespace Volo.Abp; + +public class AbpHostEnvironment : IAbpHostEnvironment +{ + public string EnvironmentName { get; set; } +} diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/AbpHostEnvironmentExtensions.cs b/framework/src/Volo.Abp.Core/Volo/Abp/AbpHostEnvironmentExtensions.cs new file mode 100644 index 0000000000..57d7a44c06 --- /dev/null +++ b/framework/src/Volo.Abp.Core/Volo/Abp/AbpHostEnvironmentExtensions.cs @@ -0,0 +1,38 @@ +using System; +using Microsoft.Extensions.Hosting; + +namespace Volo.Abp; + +public static class AbpHostEnvironmentExtensions +{ + public static bool IsDevelopment(this IAbpHostEnvironment hostEnvironment) + { + Check.NotNull(hostEnvironment, nameof(hostEnvironment)); + + return hostEnvironment.IsEnvironment(Environments.Development); + } + + public static bool IsStaging(this IAbpHostEnvironment hostEnvironment) + { + Check.NotNull(hostEnvironment, nameof(hostEnvironment)); + + return hostEnvironment.IsEnvironment(Environments.Staging); + } + + public static bool IsProduction(this IAbpHostEnvironment hostEnvironment) + { + Check.NotNull(hostEnvironment, nameof(hostEnvironment)); + + return hostEnvironment.IsEnvironment(Environments.Production); + } + + public static bool IsEnvironment(this IAbpHostEnvironment hostEnvironment, string environmentName) + { + Check.NotNull(hostEnvironment, nameof(hostEnvironment)); + + return string.Equals( + hostEnvironment.EnvironmentName, + environmentName, + StringComparison.OrdinalIgnoreCase); + } +} diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/IAbpHostEnvironment.cs b/framework/src/Volo.Abp.Core/Volo/Abp/IAbpHostEnvironment.cs new file mode 100644 index 0000000000..383361b9ed --- /dev/null +++ b/framework/src/Volo.Abp.Core/Volo/Abp/IAbpHostEnvironment.cs @@ -0,0 +1,6 @@ +namespace Volo.Abp; + +public interface IAbpHostEnvironment +{ + string EnvironmentName { get; set; } +} diff --git a/framework/src/Volo.Abp.IdentityModel/Volo/Abp/IdentityModel/IdentityModelAuthenticationService.cs b/framework/src/Volo.Abp.IdentityModel/Volo/Abp/IdentityModel/IdentityModelAuthenticationService.cs index db59346465..a900dc3d03 100644 --- a/framework/src/Volo.Abp.IdentityModel/Volo/Abp/IdentityModel/IdentityModelAuthenticationService.cs +++ b/framework/src/Volo.Abp.IdentityModel/Volo/Abp/IdentityModel/IdentityModelAuthenticationService.cs @@ -29,6 +29,7 @@ public class IdentityModelAuthenticationService : IIdentityModelAuthenticationSe protected IdentityModelHttpRequestMessageOptions IdentityModelHttpRequestMessageOptions { get; } protected IDistributedCache TokenCache { get; } protected IDistributedCache DiscoveryDocumentCache { get; } + protected IAbpHostEnvironment AbpHostEnvironment { get; } public IdentityModelAuthenticationService( IOptions options, @@ -37,7 +38,8 @@ public class IdentityModelAuthenticationService : IIdentityModelAuthenticationSe ICurrentTenant currentTenant, IOptions identityModelHttpRequestMessageOptions, IDistributedCache tokenCache, - IDistributedCache discoveryDocumentCache) + IDistributedCache discoveryDocumentCache, + IAbpHostEnvironment abpHostEnvironment) { ClientOptions = options.Value; CancellationTokenProvider = cancellationTokenProvider; @@ -45,6 +47,7 @@ public class IdentityModelAuthenticationService : IIdentityModelAuthenticationSe CurrentTenant = currentTenant; TokenCache = tokenCache; DiscoveryDocumentCache = discoveryDocumentCache; + AbpHostEnvironment = abpHostEnvironment; IdentityModelHttpRequestMessageOptions = identityModelHttpRequestMessageOptions.Value; Logger = NullLogger.Instance; } @@ -97,11 +100,12 @@ public class IdentityModelAuthenticationService : IIdentityModelAuthenticationSe } tokenCacheItem = new IdentityModelTokenCacheItem(tokenResponse.AccessToken); - await TokenCache.SetAsync(cacheKey, tokenCacheItem, - new DistributedCacheEntryOptions - { - AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(configuration.CacheAbsoluteExpiration) - }); + await TokenCache.SetAsync(cacheKey, tokenCacheItem, new DistributedCacheEntryOptions + { + AbsoluteExpirationRelativeToNow = AbpHostEnvironment.IsDevelopment() + ? TimeSpan.Zero + : TimeSpan.FromSeconds(configuration.CacheAbsoluteExpiration) + }); } return tokenCacheItem.AccessToken; @@ -146,7 +150,9 @@ public class IdentityModelAuthenticationService : IIdentityModelAuthenticationSe await DiscoveryDocumentCache.SetAsync(tokenEndpointUrlCacheKey, discoveryDocumentCacheItem, new DistributedCacheEntryOptions { - AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(configuration.CacheAbsoluteExpiration) + AbsoluteExpirationRelativeToNow = AbpHostEnvironment.IsDevelopment() + ? TimeSpan.Zero + : TimeSpan.FromSeconds(configuration.CacheAbsoluteExpiration) }); }