Browse Source

Merge pull request #14842 from abpframework/IAbpHostEnvironment

Introduce `IAbpHostEnvironment` and reduce cache durations for development environment.
pull/15117/head
Halil İbrahim Kalkan 4 years ago
committed by GitHub
parent
commit
527188c6fd
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 8
      framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Microsoft/AspNetCore/Components/WebAssembly/Hosting/AbpWebAssemblyHostBuilderExtensions.cs
  2. 19
      framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Microsoft/Extensions/DependencyInjection/AbpWebAssemblyServiceCollectionExtensions.cs
  3. 10
      framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Microsoft/Extensions/DependencyInjection/EmptyWebAssemblyHostEnvironment.cs
  4. 6
      framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/AbpAspNetCoreComponentsWebAssemblyModule.cs
  5. 16
      framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/AbpAspNetCoreMvcClientCacheOptions.cs
  6. 15
      framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/AbpAspNetCoreMvcClientModule.cs
  7. 14
      framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcCachedApplicationConfigurationClient.cs
  8. 26
      framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcRemoteTenantStore.cs
  9. 12
      framework/src/Volo.Abp.AspNetCore/Microsoft/Extensions/DependencyInjection/WebApplicationBuilderExtensions.cs
  10. 15
      framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/AbpAspNetCoreModule.cs
  11. 10
      framework/src/Volo.Abp.Core/Microsoft/Extensions/DependencyInjection/ServiceCollectionApplicationExtensions.cs
  12. 18
      framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationBase.cs
  13. 5
      framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationCreationOptions.cs
  14. 6
      framework/src/Volo.Abp.Core/Volo/Abp/AbpHostEnvironment.cs
  15. 38
      framework/src/Volo.Abp.Core/Volo/Abp/AbpHostEnvironmentExtensions.cs
  16. 6
      framework/src/Volo.Abp.Core/Volo/Abp/IAbpHostEnvironment.cs
  17. 20
      framework/src/Volo.Abp.IdentityModel/Volo/Abp/IdentityModel/IdentityModelAuthenticationService.cs
  18. 65
      framework/test/Volo.Abp.AspNetCore.Tests/Volo/Abp/AspNetCore/AbpHostEnvironment_Tests.cs
  19. 32
      framework/test/Volo.Abp.Core.Tests/Volo/Abp/AbpApplication_Initialize_Tests.cs

8
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<TStartupModule>(opts => var application = await builder.Services.AddApplicationAsync<TStartupModule>(opts =>
{ {
options?.Invoke(new AbpWebAssemblyApplicationCreationOptions(builder, opts)); options?.Invoke(new AbpWebAssemblyApplicationCreationOptions(builder, opts));
if (opts.Environment.IsNullOrWhiteSpace())
{
opts.Environment = builder.HostEnvironment.Environment;
}
}); });
return application; return application;
@ -57,6 +61,10 @@ public static class AbpWebAssemblyHostBuilderExtensions
var application = builder.Services.AddApplication<TStartupModule>(opts => var application = builder.Services.AddApplication<TStartupModule>(opts =>
{ {
options?.Invoke(new AbpWebAssemblyApplicationCreationOptions(builder, opts)); options?.Invoke(new AbpWebAssemblyApplicationCreationOptions(builder, opts));
if (opts.Environment.IsNullOrWhiteSpace())
{
opts.Environment = builder.HostEnvironment.Environment;
}
}); });
return application; return application;

19
framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Microsoft/Extensions/DependencyInjection/AbpWebAssemblyServiceCollectionExtensions.cs

@ -1,16 +1,31 @@
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting; using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using Microsoft.Extensions.Hosting;
using Volo.Abp; using Volo.Abp;
namespace Microsoft.Extensions.DependencyInjection; namespace Microsoft.Extensions.DependencyInjection;
public static class AbpWebAssemblyServiceCollectionExtensions public static class AbpWebAssemblyServiceCollectionExtensions
{ {
public static WebAssemblyHostBuilder GetHostBuilder( public static WebAssemblyHostBuilder GetHostBuilder([NotNull] this IServiceCollection services)
[NotNull] this IServiceCollection services)
{ {
Check.NotNull(services, nameof(services)); Check.NotNull(services, nameof(services));
return services.GetSingletonInstance<WebAssemblyHostBuilder>(); return services.GetSingletonInstance<WebAssemblyHostBuilder>();
} }
public static IWebAssemblyHostEnvironment GetWebAssemblyHostEnvironment(this IServiceCollection services)
{
var webAssemblyHostEnvironment = services.GetSingletonInstanceOrNull<IWebAssemblyHostEnvironment>();
if (webAssemblyHostEnvironment == null)
{
return new EmptyWebAssemblyHostEnvironment()
{
Environment = Environments.Development
};
}
return webAssemblyHostEnvironment;
}
} }

10
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; }
}

6
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) public override void PreConfigureServices(ServiceConfigurationContext context)
{ {
var abpHostEnvironment = context.Services.GetSingletonInstance<IAbpHostEnvironment>();
if (abpHostEnvironment.EnvironmentName.IsNullOrWhiteSpace())
{
abpHostEnvironment.EnvironmentName = context.Services.GetWebAssemblyHostEnvironment().Environment;
}
PreConfigure<AbpHttpClientBuilderOptions>(options => PreConfigure<AbpHttpClientBuilderOptions>(options =>
{ {
options.ProxyClientBuildActions.Add((_, builder) => options.ProxyClientBuildActions.Add((_, builder) =>

16
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);
}
}

15
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.EventBus;
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
@ -9,5 +11,16 @@ namespace Volo.Abp.AspNetCore.Mvc.Client;
)] )]
public class AbpAspNetCoreMvcClientModule : AbpModule public class AbpAspNetCoreMvcClientModule : AbpModule
{ {
public override void ConfigureServices(ServiceConfigurationContext context)
{
var abpHostEnvironment = context.Services.GetAbpHostEnvironment();
if (abpHostEnvironment.IsDevelopment())
{
Configure<AbpAspNetCoreMvcClientCacheOptions>(options =>
{
options.TenantConfigurationCacheAbsoluteExpiration = TimeSpan.FromSeconds(5);
options.ApplicationConfigurationDtoCacheAbsoluteExpiration = TimeSpan.FromSeconds(5);
});
}
}
} }

14
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 Microsoft.AspNetCore.Http;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.Extensions.Caching.Distributed; using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Options;
using Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations; using Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations;
using Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ClientProxies; using Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ClientProxies;
using Volo.Abp.Caching; using Volo.Abp.Caching;
@ -18,18 +19,21 @@ public class MvcCachedApplicationConfigurationClient : ICachedApplicationConfigu
protected AbpApplicationLocalizationClientProxy ApplicationLocalizationClientProxy { get; } protected AbpApplicationLocalizationClientProxy ApplicationLocalizationClientProxy { get; }
protected ICurrentUser CurrentUser { get; } protected ICurrentUser CurrentUser { get; }
protected IDistributedCache<ApplicationConfigurationDto> Cache { get; } protected IDistributedCache<ApplicationConfigurationDto> Cache { get; }
protected AbpAspNetCoreMvcClientCacheOptions Options { get; }
public MvcCachedApplicationConfigurationClient( public MvcCachedApplicationConfigurationClient(
IDistributedCache<ApplicationConfigurationDto> cache, IDistributedCache<ApplicationConfigurationDto> cache,
AbpApplicationConfigurationClientProxy applicationConfigurationAppService, AbpApplicationConfigurationClientProxy applicationConfigurationAppService,
ICurrentUser currentUser, ICurrentUser currentUser,
IHttpContextAccessor httpContextAccessor, IHttpContextAccessor httpContextAccessor,
AbpApplicationLocalizationClientProxy applicationLocalizationClientProxy) AbpApplicationLocalizationClientProxy applicationLocalizationClientProxy,
IOptions<AbpAspNetCoreMvcClientCacheOptions> options)
{ {
ApplicationConfigurationAppService = applicationConfigurationAppService; ApplicationConfigurationAppService = applicationConfigurationAppService;
CurrentUser = currentUser; CurrentUser = currentUser;
HttpContextAccessor = httpContextAccessor; HttpContextAccessor = httpContextAccessor;
ApplicationLocalizationClientProxy = applicationLocalizationClientProxy; ApplicationLocalizationClientProxy = applicationLocalizationClientProxy;
Options = options.Value;
Cache = cache; Cache = cache;
} }
@ -48,7 +52,7 @@ public class MvcCachedApplicationConfigurationClient : ICachedApplicationConfigu
async () => await GetRemoteConfigurationAsync(), async () => await GetRemoteConfigurationAsync(),
() => new DistributedCacheEntryOptions () => new DistributedCacheEntryOptions
{ {
AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(300) //TODO: Should be configurable. AbsoluteExpirationRelativeToNow = Options.ApplicationConfigurationDtoCacheAbsoluteExpiration
} }
); );
@ -68,7 +72,7 @@ public class MvcCachedApplicationConfigurationClient : ICachedApplicationConfigu
IncludeLocalizationResources = false IncludeLocalizationResources = false
} }
); );
var localizationDto = await ApplicationLocalizationClientProxy.GetAsync( var localizationDto = await ApplicationLocalizationClientProxy.GetAsync(
new ApplicationLocalizationRequestDto { new ApplicationLocalizationRequestDto {
CultureName = config.Localization.CurrentCulture.Name, CultureName = config.Localization.CurrentCulture.Name,
@ -77,7 +81,7 @@ public class MvcCachedApplicationConfigurationClient : ICachedApplicationConfigu
); );
config.Localization.Resources = localizationDto.Resources; config.Localization.Resources = localizationDto.Resources;
return config; return config;
} }

26
framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcRemoteTenantStore.cs

@ -2,6 +2,7 @@
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Caching.Distributed; using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Options;
using Pages.Abp.MultiTenancy.ClientProxies; using Pages.Abp.MultiTenancy.ClientProxies;
using Volo.Abp.AspNetCore.Mvc.MultiTenancy; using Volo.Abp.AspNetCore.Mvc.MultiTenancy;
using Volo.Abp.Caching; using Volo.Abp.Caching;
@ -16,15 +17,18 @@ public class MvcRemoteTenantStore : ITenantStore, ITransientDependency
protected AbpTenantClientProxy TenantAppService { get; } protected AbpTenantClientProxy TenantAppService { get; }
protected IHttpContextAccessor HttpContextAccessor { get; } protected IHttpContextAccessor HttpContextAccessor { get; }
protected IDistributedCache<TenantConfiguration> Cache { get; } protected IDistributedCache<TenantConfiguration> Cache { get; }
protected AbpAspNetCoreMvcClientCacheOptions Options { get; }
public MvcRemoteTenantStore( public MvcRemoteTenantStore(
AbpTenantClientProxy tenantAppService, AbpTenantClientProxy tenantAppService,
IHttpContextAccessor httpContextAccessor, IHttpContextAccessor httpContextAccessor,
IDistributedCache<TenantConfiguration> cache) IDistributedCache<TenantConfiguration> cache,
IOptions<AbpAspNetCoreMvcClientCacheOptions> options)
{ {
TenantAppService = tenantAppService; TenantAppService = tenantAppService;
HttpContextAccessor = httpContextAccessor; HttpContextAccessor = httpContextAccessor;
Cache = cache; Cache = cache;
Options = options.Value;
} }
public async Task<TenantConfiguration> FindAsync(string name) public async Task<TenantConfiguration> FindAsync(string name)
@ -42,9 +46,8 @@ public class MvcRemoteTenantStore : ITenantStore, ITransientDependency
async () => CreateTenantConfiguration(await TenantAppService.FindTenantByNameAsync(name)), async () => CreateTenantConfiguration(await TenantAppService.FindTenantByNameAsync(name)),
() => new DistributedCacheEntryOptions () => new DistributedCacheEntryOptions
{ {
AbsoluteExpirationRelativeToNow = AbsoluteExpirationRelativeToNow = Options.TenantConfigurationCacheAbsoluteExpiration
TimeSpan.FromMinutes(5) //TODO: Should be configurable. }
}
); );
if (httpContext != null) if (httpContext != null)
@ -70,9 +73,8 @@ public class MvcRemoteTenantStore : ITenantStore, ITransientDependency
async () => CreateTenantConfiguration(await TenantAppService.FindTenantByIdAsync(id)), async () => CreateTenantConfiguration(await TenantAppService.FindTenantByIdAsync(id)),
() => new DistributedCacheEntryOptions () => new DistributedCacheEntryOptions
{ {
AbsoluteExpirationRelativeToNow = AbsoluteExpirationRelativeToNow = Options.TenantConfigurationCacheAbsoluteExpiration
TimeSpan.FromMinutes(5) //TODO: Should be configurable. }
}
); );
if (httpContext != null) if (httpContext != null)
@ -98,9 +100,8 @@ public class MvcRemoteTenantStore : ITenantStore, ITransientDependency
() => AsyncHelper.RunSync(async () => CreateTenantConfiguration(await TenantAppService.FindTenantByNameAsync(name))), () => AsyncHelper.RunSync(async () => CreateTenantConfiguration(await TenantAppService.FindTenantByNameAsync(name))),
() => new DistributedCacheEntryOptions () => new DistributedCacheEntryOptions
{ {
AbsoluteExpirationRelativeToNow = AbsoluteExpirationRelativeToNow = Options.TenantConfigurationCacheAbsoluteExpiration
TimeSpan.FromMinutes(5) //TODO: Should be configurable. }
}
); );
if (httpContext != null) if (httpContext != null)
@ -126,9 +127,8 @@ public class MvcRemoteTenantStore : ITenantStore, ITransientDependency
() => AsyncHelper.RunSync(async () => CreateTenantConfiguration(await TenantAppService.FindTenantByIdAsync(id))), () => AsyncHelper.RunSync(async () => CreateTenantConfiguration(await TenantAppService.FindTenantByIdAsync(id))),
() => new DistributedCacheEntryOptions () => new DistributedCacheEntryOptions
{ {
AbsoluteExpirationRelativeToNow = AbsoluteExpirationRelativeToNow = Options.TenantConfigurationCacheAbsoluteExpiration
TimeSpan.FromMinutes(5) //TODO: Should be configurable. }
}
); );
if (httpContext != null) if (httpContext != null)

12
framework/src/Volo.Abp.AspNetCore/Microsoft/Extensions/DependencyInjection/WebApplicationBuilderExtensions.cs

@ -9,7 +9,7 @@ namespace Microsoft.Extensions.DependencyInjection;
public static class WebApplicationBuilderExtensions public static class WebApplicationBuilderExtensions
{ {
public async static Task<IAbpApplicationWithExternalServiceProvider> AddApplicationAsync<TStartupModule>( public static async Task<IAbpApplicationWithExternalServiceProvider> AddApplicationAsync<TStartupModule>(
[NotNull] this WebApplicationBuilder builder, [NotNull] this WebApplicationBuilder builder,
[CanBeNull] Action<AbpApplicationCreationOptions> optionsAction = null) [CanBeNull] Action<AbpApplicationCreationOptions> optionsAction = null)
where TStartupModule : IAbpModule where TStartupModule : IAbpModule
@ -18,10 +18,14 @@ public static class WebApplicationBuilderExtensions
{ {
options.Services.ReplaceConfiguration(builder.Configuration); options.Services.ReplaceConfiguration(builder.Configuration);
optionsAction?.Invoke(options); optionsAction?.Invoke(options);
if (options.Environment.IsNullOrWhiteSpace())
{
options.Environment = builder.Environment.EnvironmentName;
}
}); });
} }
public async static Task<IAbpApplicationWithExternalServiceProvider> AddApplicationAsync( public static async Task<IAbpApplicationWithExternalServiceProvider> AddApplicationAsync(
[NotNull] this WebApplicationBuilder builder, [NotNull] this WebApplicationBuilder builder,
[NotNull] Type startupModuleType, [NotNull] Type startupModuleType,
[CanBeNull] Action<AbpApplicationCreationOptions> optionsAction = null) [CanBeNull] Action<AbpApplicationCreationOptions> optionsAction = null)
@ -30,6 +34,10 @@ public static class WebApplicationBuilderExtensions
{ {
options.Services.ReplaceConfiguration(builder.Configuration); options.Services.ReplaceConfiguration(builder.Configuration);
optionsAction?.Invoke(options); optionsAction?.Invoke(options);
if (options.Environment.IsNullOrWhiteSpace())
{
options.Environment = builder.Environment.EnvironmentName;
}
}); });
} }
} }

15
framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/AbpAspNetCoreModule.cs

@ -1,10 +1,8 @@
using Microsoft.AspNetCore.Builder; using System;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.RequestLocalization; using Microsoft.AspNetCore.RequestLocalization;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.FileProviders; using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Options;
using Volo.Abp.AspNetCore.Auditing; using Volo.Abp.AspNetCore.Auditing;
using Volo.Abp.AspNetCore.VirtualFileSystem; using Volo.Abp.AspNetCore.VirtualFileSystem;
using Volo.Abp.Auditing; using Volo.Abp.Auditing;
@ -31,6 +29,15 @@ namespace Volo.Abp.AspNetCore;
)] )]
public class AbpAspNetCoreModule : AbpModule public class AbpAspNetCoreModule : AbpModule
{ {
public override void PreConfigureServices(ServiceConfigurationContext context)
{
var abpHostEnvironment = context.Services.GetSingletonInstance<IAbpHostEnvironment>();
if (abpHostEnvironment.EnvironmentName.IsNullOrWhiteSpace())
{
abpHostEnvironment.EnvironmentName = context.Services.GetHostingEnvironment().EnvironmentName;
}
}
public override void ConfigureServices(ServiceConfigurationContext context) public override void ConfigureServices(ServiceConfigurationContext context)
{ {
context.Services.AddAuthorization(); context.Services.AddAuthorization();

10
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); return await AbpApplicationFactory.CreateAsync(startupModuleType, services, optionsAction);
} }
[CanBeNull] [CanBeNull]
public static string GetApplicationName(this IServiceCollection services) public static string GetApplicationName(this IServiceCollection services)
{ {
return services.GetSingletonInstance<IApplicationInfoAccessor>().ApplicationName; return services.GetSingletonInstance<IApplicationInfoAccessor>().ApplicationName;
} }
[NotNull] [NotNull]
public static string GetApplicationInstanceId(this IServiceCollection services) public static string GetApplicationInstanceId(this IServiceCollection services)
{ {
return services.GetSingletonInstance<IApplicationInfoAccessor>().InstanceId; return services.GetSingletonInstance<IApplicationInfoAccessor>().InstanceId;
} }
[NotNull]
public static IAbpHostEnvironment GetAbpHostEnvironment(this IServiceCollection services)
{
return services.GetSingletonInstance<IAbpHostEnvironment>();
}
} }

18
framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationBase.cs

@ -5,6 +5,7 @@ using System.Reflection;
using System.Threading.Tasks; using System.Threading.Tasks;
using JetBrains.Annotations; using JetBrains.Annotations;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
using Volo.Abp.Internal; using Volo.Abp.Internal;
@ -51,6 +52,10 @@ public abstract class AbpApplicationBase : IAbpApplication
services.AddSingleton<IAbpApplication>(this); services.AddSingleton<IAbpApplication>(this);
services.AddSingleton<IApplicationInfoAccessor>(this); services.AddSingleton<IApplicationInfoAccessor>(this);
services.AddSingleton<IModuleContainer>(this); services.AddSingleton<IModuleContainer>(this);
services.AddSingleton<IAbpHostEnvironment>(new AbpHostEnvironment()
{
EnvironmentName = options.Environment
});
services.AddCoreServices(); services.AddCoreServices();
services.AddCoreAbpServices(this, options); services.AddCoreAbpServices(this, options);
@ -224,6 +229,8 @@ public abstract class AbpApplicationBase : IAbpApplication
} }
_configuredServices = true; _configuredServices = true;
TryToSetEnvironment(Services);
} }
private void CheckMultipleConfigureServices() private void CheckMultipleConfigureServices()
@ -313,6 +320,8 @@ public abstract class AbpApplicationBase : IAbpApplication
} }
_configuredServices = true; _configuredServices = true;
TryToSetEnvironment(Services);
} }
private static string GetApplicationName(AbpApplicationCreationOptions options) private static string GetApplicationName(AbpApplicationCreationOptions options)
@ -340,4 +349,13 @@ public abstract class AbpApplicationBase : IAbpApplication
return null; return null;
} }
private static void TryToSetEnvironment(IServiceCollection services)
{
var abpHostEnvironment = services.GetSingletonInstance<IAbpHostEnvironment>();
if (abpHostEnvironment.EnvironmentName.IsNullOrWhiteSpace())
{
abpHostEnvironment.EnvironmentName = Environments.Production;
}
}
} }

5
framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationCreationOptions.cs

@ -20,10 +20,13 @@ public class AbpApplicationCreationOptions
public AbpConfigurationBuilderOptions Configuration { get; } public AbpConfigurationBuilderOptions Configuration { get; }
public bool SkipConfigureServices { get; set; } public bool SkipConfigureServices { get; set; }
[CanBeNull] [CanBeNull]
public string ApplicationName { get; set; } public string ApplicationName { get; set; }
[CanBeNull]
public string Environment { get; set; }
public AbpApplicationCreationOptions([NotNull] IServiceCollection services) public AbpApplicationCreationOptions([NotNull] IServiceCollection services)
{ {
Services = Check.NotNull(services, nameof(services)); Services = Check.NotNull(services, nameof(services));

6
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; }
}

38
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);
}
}

6
framework/src/Volo.Abp.Core/Volo/Abp/IAbpHostEnvironment.cs

@ -0,0 +1,6 @@
namespace Volo.Abp;
public interface IAbpHostEnvironment
{
string EnvironmentName { get; set; }
}

20
framework/src/Volo.Abp.IdentityModel/Volo/Abp/IdentityModel/IdentityModelAuthenticationService.cs

@ -29,6 +29,7 @@ public class IdentityModelAuthenticationService : IIdentityModelAuthenticationSe
protected IdentityModelHttpRequestMessageOptions IdentityModelHttpRequestMessageOptions { get; } protected IdentityModelHttpRequestMessageOptions IdentityModelHttpRequestMessageOptions { get; }
protected IDistributedCache<IdentityModelTokenCacheItem> TokenCache { get; } protected IDistributedCache<IdentityModelTokenCacheItem> TokenCache { get; }
protected IDistributedCache<IdentityModelDiscoveryDocumentCacheItem> DiscoveryDocumentCache { get; } protected IDistributedCache<IdentityModelDiscoveryDocumentCacheItem> DiscoveryDocumentCache { get; }
protected IAbpHostEnvironment AbpHostEnvironment { get; }
public IdentityModelAuthenticationService( public IdentityModelAuthenticationService(
IOptions<AbpIdentityClientOptions> options, IOptions<AbpIdentityClientOptions> options,
@ -37,7 +38,8 @@ public class IdentityModelAuthenticationService : IIdentityModelAuthenticationSe
ICurrentTenant currentTenant, ICurrentTenant currentTenant,
IOptions<IdentityModelHttpRequestMessageOptions> identityModelHttpRequestMessageOptions, IOptions<IdentityModelHttpRequestMessageOptions> identityModelHttpRequestMessageOptions,
IDistributedCache<IdentityModelTokenCacheItem> tokenCache, IDistributedCache<IdentityModelTokenCacheItem> tokenCache,
IDistributedCache<IdentityModelDiscoveryDocumentCacheItem> discoveryDocumentCache) IDistributedCache<IdentityModelDiscoveryDocumentCacheItem> discoveryDocumentCache,
IAbpHostEnvironment abpHostEnvironment)
{ {
ClientOptions = options.Value; ClientOptions = options.Value;
CancellationTokenProvider = cancellationTokenProvider; CancellationTokenProvider = cancellationTokenProvider;
@ -45,6 +47,7 @@ public class IdentityModelAuthenticationService : IIdentityModelAuthenticationSe
CurrentTenant = currentTenant; CurrentTenant = currentTenant;
TokenCache = tokenCache; TokenCache = tokenCache;
DiscoveryDocumentCache = discoveryDocumentCache; DiscoveryDocumentCache = discoveryDocumentCache;
AbpHostEnvironment = abpHostEnvironment;
IdentityModelHttpRequestMessageOptions = identityModelHttpRequestMessageOptions.Value; IdentityModelHttpRequestMessageOptions = identityModelHttpRequestMessageOptions.Value;
Logger = NullLogger<IdentityModelAuthenticationService>.Instance; Logger = NullLogger<IdentityModelAuthenticationService>.Instance;
} }
@ -97,11 +100,12 @@ public class IdentityModelAuthenticationService : IIdentityModelAuthenticationSe
} }
tokenCacheItem = new IdentityModelTokenCacheItem(tokenResponse.AccessToken); tokenCacheItem = new IdentityModelTokenCacheItem(tokenResponse.AccessToken);
await TokenCache.SetAsync(cacheKey, tokenCacheItem, await TokenCache.SetAsync(cacheKey, tokenCacheItem, new DistributedCacheEntryOptions
new DistributedCacheEntryOptions {
{ AbsoluteExpirationRelativeToNow = AbpHostEnvironment.IsDevelopment()
AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(configuration.CacheAbsoluteExpiration) ? TimeSpan.FromSeconds(5)
}); : TimeSpan.FromSeconds(configuration.CacheAbsoluteExpiration)
});
} }
return tokenCacheItem.AccessToken; return tokenCacheItem.AccessToken;
@ -146,7 +150,9 @@ public class IdentityModelAuthenticationService : IIdentityModelAuthenticationSe
await DiscoveryDocumentCache.SetAsync(tokenEndpointUrlCacheKey, discoveryDocumentCacheItem, await DiscoveryDocumentCache.SetAsync(tokenEndpointUrlCacheKey, discoveryDocumentCacheItem,
new DistributedCacheEntryOptions new DistributedCacheEntryOptions
{ {
AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(configuration.CacheAbsoluteExpiration) AbsoluteExpirationRelativeToNow = AbpHostEnvironment.IsDevelopment()
? TimeSpan.FromSeconds(5)
: TimeSpan.FromSeconds(configuration.CacheAbsoluteExpiration)
}); });
} }

65
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<Startup>
{
protected override IHostBuilder CreateHostBuilder()
{
var builder = base.CreateHostBuilder();
builder.ConfigureHostConfiguration(x => x.Sources.Insert(0,
new MemoryConfigurationSource()
{
InitialData = new List<KeyValuePair<string, string>>
{
new(HostDefaults.EnvironmentKey, Environments.Staging),
}
}));
return builder;
}
[Fact]
public void Should_Set_Environment_From_IWebHostEnvironment()
{
var abpHostEnvironment = GetRequiredService<IAbpHostEnvironment>();
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<AbpAspNetCoreTestModule>();
var app = builder.Build();
await app.InitializeApplicationAsync();
var abpHostEnvironment = app.Services.GetRequiredService<IAbpHostEnvironment>();
abpHostEnvironment.EnvironmentName.ShouldBe(Environments.Staging);
builder = WebApplication.CreateBuilder(new WebApplicationOptions
{
EnvironmentName = Environments.Staging
});
builder.Host.UseAutofac();
var abpApp = await AbpApplicationFactory.CreateAsync<AbpAspNetCoreTestModule>(builder.Services);
app = builder.Build();
await app.InitializeApplicationAsync();
abpHostEnvironment = abpApp.Services.GetRequiredService<IAbpHostEnvironment>();
abpHostEnvironment.EnvironmentName.ShouldBe(Environments.Staging);
}
}

32
framework/test/Volo.Abp.Core.Tests/Volo/Abp/AbpApplication_Initialize_Tests.cs

@ -4,6 +4,7 @@ using System.Reflection;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using NSubstitute; using NSubstitute;
using Shouldly; using Shouldly;
using Volo.Abp.DependencyInjection; 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<IndependentEmptyModule>())
{
var abpHostEnvironment = application.Services.GetSingletonInstance<IAbpHostEnvironment>();
abpHostEnvironment.EnvironmentName.ShouldBe(Environments.Production);
application.Initialize();
abpHostEnvironment = application.ServiceProvider.GetRequiredService<IAbpHostEnvironment>();
abpHostEnvironment.EnvironmentName.ShouldBe(Environments.Production);
}
// Set environment
using (var application = AbpApplicationFactory.Create<IndependentEmptyModule>(options =>
{
options.Environment = Environments.Staging;
}))
{
var abpHostEnvironment = application.Services.GetSingletonInstance<IAbpHostEnvironment>();
abpHostEnvironment.EnvironmentName.ShouldBe(Environments.Staging);
application.Initialize();
abpHostEnvironment = application.ServiceProvider.GetRequiredService<IAbpHostEnvironment>();
abpHostEnvironment.EnvironmentName.ShouldBe(Environments.Staging);
}
}
[Fact] [Fact]
public async Task Should_Resolve_Root_Service_Provider() public async Task Should_Resolve_Root_Service_Provider()
{ {

Loading…
Cancel
Save