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.Components.WebAssembly/Microsoft/Extensions/DependencyInjection/AbpWebAssemblyServiceCollectionExtensions.cs b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Microsoft/Extensions/DependencyInjection/AbpWebAssemblyServiceCollectionExtensions.cs index bbcf1d5a83..bb9f0774bc 100644 --- a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Microsoft/Extensions/DependencyInjection/AbpWebAssemblyServiceCollectionExtensions.cs +++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Microsoft/Extensions/DependencyInjection/AbpWebAssemblyServiceCollectionExtensions.cs @@ -1,16 +1,31 @@ using System.Diagnostics.CodeAnalysis; using Microsoft.AspNetCore.Components.WebAssembly.Hosting; +using Microsoft.Extensions.Hosting; using Volo.Abp; namespace Microsoft.Extensions.DependencyInjection; public static class AbpWebAssemblyServiceCollectionExtensions { - public static WebAssemblyHostBuilder GetHostBuilder( - [NotNull] this IServiceCollection services) + public static WebAssemblyHostBuilder GetHostBuilder([NotNull] this IServiceCollection services) { Check.NotNull(services, nameof(services)); return services.GetSingletonInstance(); } + + public static IWebAssemblyHostEnvironment GetWebAssemblyHostEnvironment(this IServiceCollection services) + { + var webAssemblyHostEnvironment = services.GetSingletonInstanceOrNull(); + + if (webAssemblyHostEnvironment == null) + { + return new EmptyWebAssemblyHostEnvironment() + { + Environment = Environments.Development + }; + } + + return webAssemblyHostEnvironment; + } } diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Microsoft/Extensions/DependencyInjection/EmptyWebAssemblyHostEnvironment.cs b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Microsoft/Extensions/DependencyInjection/EmptyWebAssemblyHostEnvironment.cs new file mode 100644 index 0000000000..6393948af7 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Microsoft/Extensions/DependencyInjection/EmptyWebAssemblyHostEnvironment.cs @@ -0,0 +1,10 @@ +using Microsoft.AspNetCore.Components.WebAssembly.Hosting; + +namespace Microsoft.Extensions.DependencyInjection; + +public class EmptyWebAssemblyHostEnvironment : IWebAssemblyHostEnvironment +{ + public string Environment { get; set; } + + public string BaseAddress { get; set; } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/AbpAspNetCoreComponentsWebAssemblyModule.cs b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/AbpAspNetCoreComponentsWebAssemblyModule.cs index 12877f0c31..b18fdab82e 100644 --- a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/AbpAspNetCoreComponentsWebAssemblyModule.cs +++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/AbpAspNetCoreComponentsWebAssemblyModule.cs @@ -24,6 +24,12 @@ public class AbpAspNetCoreComponentsWebAssemblyModule : AbpModule { public override void PreConfigureServices(ServiceConfigurationContext context) { + var abpHostEnvironment = context.Services.GetSingletonInstance(); + if (abpHostEnvironment.EnvironmentName.IsNullOrWhiteSpace()) + { + abpHostEnvironment.EnvironmentName = context.Services.GetWebAssemblyHostEnvironment().Environment; + } + PreConfigure(options => { options.ProxyClientBuildActions.Add((_, builder) => 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..c27670246e --- /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); + ApplicationConfigurationDtoCacheAbsoluteExpiration = 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..610a41eefd 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.FromSeconds(5); + options.ApplicationConfigurationDtoCacheAbsoluteExpiration = TimeSpan.FromSeconds(5); + }); + } + } } 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.AspNetCore/Volo/Abp/AspNetCore/AbpAspNetCoreModule.cs b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/AbpAspNetCoreModule.cs index 9f613122c8..bad4b7c491 100644 --- a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/AbpAspNetCoreModule.cs +++ b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/AbpAspNetCoreModule.cs @@ -1,10 +1,8 @@ -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; +using System; +using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.RequestLocalization; using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.FileProviders; -using Microsoft.Extensions.Options; using Volo.Abp.AspNetCore.Auditing; using Volo.Abp.AspNetCore.VirtualFileSystem; using Volo.Abp.Auditing; @@ -31,6 +29,15 @@ namespace Volo.Abp.AspNetCore; )] public class AbpAspNetCoreModule : AbpModule { + public override void PreConfigureServices(ServiceConfigurationContext context) + { + var abpHostEnvironment = context.Services.GetSingletonInstance(); + if (abpHostEnvironment.EnvironmentName.IsNullOrWhiteSpace()) + { + abpHostEnvironment.EnvironmentName = context.Services.GetHostingEnvironment().EnvironmentName; + } + } + public override void ConfigureServices(ServiceConfigurationContext context) { context.Services.AddAuthorization(); 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..609b880566 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,10 @@ public abstract class AbpApplicationBase : IAbpApplication services.AddSingleton(this); services.AddSingleton(this); services.AddSingleton(this); + services.AddSingleton(new AbpHostEnvironment() + { + EnvironmentName = options.Environment + }); services.AddCoreServices(); services.AddCoreAbpServices(this, options); @@ -224,6 +229,8 @@ public abstract class AbpApplicationBase : IAbpApplication } _configuredServices = true; + + TryToSetEnvironment(Services); } private void CheckMultipleConfigureServices() @@ -313,6 +320,8 @@ public abstract class AbpApplicationBase : IAbpApplication } _configuredServices = true; + + TryToSetEnvironment(Services); } private static string GetApplicationName(AbpApplicationCreationOptions options) @@ -340,4 +349,13 @@ public abstract class AbpApplicationBase : IAbpApplication return null; } + + private static void TryToSetEnvironment(IServiceCollection services) + { + var abpHostEnvironment = services.GetSingletonInstance(); + if (abpHostEnvironment.EnvironmentName.IsNullOrWhiteSpace()) + { + abpHostEnvironment.EnvironmentName = Environments.Production; + } + } } 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..32952a7050 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.FromSeconds(5) + : 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.FromSeconds(5) + : TimeSpan.FromSeconds(configuration.CacheAbsoluteExpiration) }); } diff --git a/framework/test/Volo.Abp.AspNetCore.Tests/Volo/Abp/AspNetCore/AbpHostEnvironment_Tests.cs b/framework/test/Volo.Abp.AspNetCore.Tests/Volo/Abp/AspNetCore/AbpHostEnvironment_Tests.cs new file mode 100644 index 0000000000..16799162bb --- /dev/null +++ b/framework/test/Volo.Abp.AspNetCore.Tests/Volo/Abp/AspNetCore/AbpHostEnvironment_Tests.cs @@ -0,0 +1,65 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.Configuration.Memory; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Shouldly; +using Xunit; + +namespace Volo.Abp.AspNetCore; + +public class AbpHostEnvironment_Tests : AbpAspNetCoreTestBase +{ + protected override IHostBuilder CreateHostBuilder() + { + var builder = base.CreateHostBuilder(); + builder.ConfigureHostConfiguration(x => x.Sources.Insert(0, + new MemoryConfigurationSource() + { + InitialData = new List> + { + new(HostDefaults.EnvironmentKey, Environments.Staging), + } + })); + return builder; + } + + [Fact] + public void Should_Set_Environment_From_IWebHostEnvironment() + { + var abpHostEnvironment = GetRequiredService(); + abpHostEnvironment.EnvironmentName.ShouldBe(Environments.Staging); + } +} + +public class AbpHostEnvironment_Async_Initialize_Tests +{ + [Fact] + public async Task Should_Set_Environment_From_AspNetCore() + { + var builder = WebApplication.CreateBuilder(new WebApplicationOptions + { + EnvironmentName = Environments.Staging + }); + builder.Host.UseAutofac(); + await builder.AddApplicationAsync(); + var app = builder.Build(); + await app.InitializeApplicationAsync(); + + var abpHostEnvironment = app.Services.GetRequiredService(); + abpHostEnvironment.EnvironmentName.ShouldBe(Environments.Staging); + + builder = WebApplication.CreateBuilder(new WebApplicationOptions + { + EnvironmentName = Environments.Staging + }); + builder.Host.UseAutofac(); + var abpApp = await AbpApplicationFactory.CreateAsync(builder.Services); + app = builder.Build(); + await app.InitializeApplicationAsync(); + + abpHostEnvironment = abpApp.Services.GetRequiredService(); + abpHostEnvironment.EnvironmentName.ShouldBe(Environments.Staging); + } +} diff --git a/framework/test/Volo.Abp.Core.Tests/Volo/Abp/AbpApplication_Initialize_Tests.cs b/framework/test/Volo.Abp.Core.Tests/Volo/Abp/AbpApplication_Initialize_Tests.cs index cf54b1492a..f910517bbc 100644 --- a/framework/test/Volo.Abp.Core.Tests/Volo/Abp/AbpApplication_Initialize_Tests.cs +++ b/framework/test/Volo.Abp.Core.Tests/Volo/Abp/AbpApplication_Initialize_Tests.cs @@ -4,6 +4,7 @@ using System.Reflection; using System.Threading.Tasks; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; using NSubstitute; using Shouldly; using Volo.Abp.DependencyInjection; @@ -204,6 +205,37 @@ public class AbpApplication_Initialize_Tests } } + [Fact] + public void Should_Set_And_Get_Environment() + { + // Default environment is Production + using (var application = AbpApplicationFactory.Create()) + { + var abpHostEnvironment = application.Services.GetSingletonInstance(); + abpHostEnvironment.EnvironmentName.ShouldBe(Environments.Production); + + application.Initialize(); + + abpHostEnvironment = application.ServiceProvider.GetRequiredService(); + abpHostEnvironment.EnvironmentName.ShouldBe(Environments.Production); + } + + // Set environment + using (var application = AbpApplicationFactory.Create(options => + { + options.Environment = Environments.Staging; + })) + { + var abpHostEnvironment = application.Services.GetSingletonInstance(); + abpHostEnvironment.EnvironmentName.ShouldBe(Environments.Staging); + + application.Initialize(); + + abpHostEnvironment = application.ServiceProvider.GetRequiredService(); + abpHostEnvironment.EnvironmentName.ShouldBe(Environments.Staging); + } + } + [Fact] public async Task Should_Resolve_Root_Service_Provider() {