Browse Source

Merge pull request #6815 from abpframework/maliming/test

Lazy Resolve Dependencies To Gain Performance
pull/7114/head
Halil İbrahim Kalkan 6 years ago
committed by GitHub
parent
commit
a5ab3b5d9b
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 25
      framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/Toolbars/ToolbarConfigurationContext.cs
  2. 30
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/BundleConfigurationContext.cs
  3. 29
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Toolbars/ToolbarConfigurationContext.cs
  4. 87
      framework/src/Volo.Abp.AspNetCore.Mvc.UI/Volo/Abp/AspNetCore/Mvc/UI/RazorPages/AbpPageModel.cs
  5. 20
      framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpActionContextExtensions.cs
  6. 86
      framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpController.cs
  7. 47
      framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpViewComponent.cs
  8. 21
      framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Auditing/AbpAuditActionFilter.cs
  9. 25
      framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Auditing/AbpAuditPageFilter.cs
  10. 48
      framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/AbpExceptionFilter.cs
  11. 45
      framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/AbpExceptionPageFilter.cs
  12. 17
      framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Features/AbpFeatureActionFilter.cs
  13. 16
      framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Features/AbpFeaturePageFilter.cs
  14. 10
      framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/GlobalFeatures/GlobalFeatureActionFilter.cs
  15. 10
      framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/GlobalFeatures/GlobalFeaturePageFilter.cs
  16. 15
      framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpHybridJsonInputFormatter.cs
  17. 73
      framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpHybridJsonOptionsSetup.cs
  18. 14
      framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpHybridJsonOutputFormatter.cs
  19. 67
      framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/MvcCoreBuilderExtensions.cs
  20. 26
      framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Uow/AbpUowActionFilter.cs
  21. 25
      framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Uow/AbpUowPageFilter.cs
  22. 9
      framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Validation/AbpValidationActionFilter.cs
  23. 87
      framework/src/Volo.Abp.AspNetCore.SignalR/Volo/Abp/AspNetCore/SignalR/AbpHub.cs
  24. 48
      framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditingInterceptor.cs
  25. 2
      framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AuthorizationInterceptor.cs
  26. 22
      framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/MethodInvocationAuthorizationService.cs
  27. 29
      framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/BackgroundWorkerBase.cs
  28. 59
      framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/AbpLazyServiceProvider.cs
  29. 23
      framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/IAbpLazyServiceProvider.cs
  30. 89
      framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/ApplicationService.cs
  31. 14
      framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/BasicRepositoryBase.cs
  32. 2
      framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/RepositoryBase.cs
  33. 54
      framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Services/DomainService.cs
  34. 12
      framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Domain/Repositories/EntityFrameworkCore/EfCoreRepository.cs
  35. 30
      framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs
  36. 26
      framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureInterceptor.cs
  37. 14
      framework/src/Volo.Abp.MemoryDb/Volo/Abp/Domain/Repositories/MemoryDb/MemoryDbRepository.cs
  38. 17
      framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/MongoDbRepository.cs
  39. 27
      framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/MenuConfigurationContext.cs
  40. 48
      framework/src/Volo.Abp.Uow/Volo/Abp/Uow/UnitOfWorkInterceptor.cs
  41. 2
      framework/src/Volo.Abp.Validation/Volo/Abp/Validation/ValidationInterceptor.cs

25
framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/Toolbars/ToolbarConfigurationContext.cs

@ -4,35 +4,19 @@ using JetBrains.Annotations;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Localization; using Microsoft.Extensions.Localization;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.AspNetCore.Components.WebAssembly.Theming.Toolbars namespace Volo.Abp.AspNetCore.Components.WebAssembly.Theming.Toolbars
{ {
public class ToolbarConfigurationContext : IToolbarConfigurationContext public class ToolbarConfigurationContext : IToolbarConfigurationContext
{ {
public IServiceProvider ServiceProvider { get; } public IServiceProvider ServiceProvider { get; }
private readonly object _serviceProviderLock = new object();
private TRef LazyGetRequiredService<TRef>(Type serviceType, ref TRef reference) private readonly IAbpLazyServiceProvider _lazyServiceProvider;
{
if (reference == null)
{
lock (_serviceProviderLock)
{
if (reference == null)
{
reference = (TRef)ServiceProvider.GetRequiredService(serviceType);
}
}
}
return reference;
}
public IAuthorizationService AuthorizationService => LazyGetRequiredService(typeof(IAuthorizationService), ref _authorizationService); public IAuthorizationService AuthorizationService => _lazyServiceProvider.LazyGetRequiredService<IAuthorizationService>();
private IAuthorizationService _authorizationService;
private IStringLocalizerFactory _stringLocalizerFactory; public IStringLocalizerFactory StringLocalizerFactory => _lazyServiceProvider.LazyGetRequiredService<IStringLocalizerFactory>();
public IStringLocalizerFactory StringLocalizerFactory => LazyGetRequiredService(typeof(IStringLocalizerFactory),ref _stringLocalizerFactory);
public Toolbar Toolbar { get; } public Toolbar Toolbar { get; }
@ -40,6 +24,7 @@ namespace Volo.Abp.AspNetCore.Components.WebAssembly.Theming.Toolbars
{ {
Toolbar = toolbar; Toolbar = toolbar;
ServiceProvider = serviceProvider; ServiceProvider = serviceProvider;
_lazyServiceProvider = ServiceProvider.GetRequiredService<IAbpLazyServiceProvider>();
} }
public Task<bool> IsGrantedAsync(string policyName) public Task<bool> IsGrantedAsync(string policyName)

30
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/BundleConfigurationContext.cs

@ -3,6 +3,7 @@ using System.Collections.Generic;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.FileProviders; using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Localization; using Volo.Abp.Localization;
namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling
@ -13,35 +14,18 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling
public IFileProvider FileProvider { get; } public IFileProvider FileProvider { get; }
public IServiceProvider ServiceProvider { get; }
private readonly IAbpLazyServiceProvider _lazyServiceProvider;
public BundleConfigurationContext(IServiceProvider serviceProvider, IFileProvider fileProvider) public BundleConfigurationContext(IServiceProvider serviceProvider, IFileProvider fileProvider)
{ {
Files = new List<string>(); Files = new List<string>();
ServiceProvider = serviceProvider; ServiceProvider = serviceProvider;
_lazyServiceProvider = ServiceProvider.GetRequiredService<IAbpLazyServiceProvider>();
FileProvider = fileProvider; FileProvider = fileProvider;
} }
public IServiceProvider ServiceProvider { get; } public AbpLocalizationOptions LocalizationOptions => _lazyServiceProvider.LazyGetRequiredService<IOptions<AbpLocalizationOptions>>().Value;
private readonly object _serviceProviderLock = new object();
private TRef LazyGetRequiredService<TRef>(Type serviceType, ref TRef reference)
{
if (reference == null)
{
lock (_serviceProviderLock)
{
if (reference == null)
{
reference = (TRef)ServiceProvider.GetRequiredService(serviceType);
}
}
}
return reference;
}
private IOptions<AbpLocalizationOptions> _abpLocalizationOptions;
public AbpLocalizationOptions LocalizationOptions =>
LazyGetRequiredService(typeof(IOptions<AbpLocalizationOptions>), ref _abpLocalizationOptions).Value;
} }
} }

29
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Toolbars/ToolbarConfigurationContext.cs

@ -5,35 +5,19 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Localization; using Microsoft.Extensions.Localization;
using Volo.Abp.AspNetCore.Mvc.UI.Theming; using Volo.Abp.AspNetCore.Mvc.UI.Theming;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Toolbars namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Toolbars
{ {
public class ToolbarConfigurationContext : IToolbarConfigurationContext public class ToolbarConfigurationContext : IToolbarConfigurationContext
{ {
public IServiceProvider ServiceProvider { get; } public IServiceProvider ServiceProvider { get; }
private readonly object _serviceProviderLock = new object();
private TRef LazyGetRequiredService<TRef>(Type serviceType, ref TRef reference) private readonly IAbpLazyServiceProvider _lazyServiceProvider;
{
if (reference == null)
{
lock (_serviceProviderLock)
{
if (reference == null)
{
reference = (TRef)ServiceProvider.GetRequiredService(serviceType);
}
}
}
return reference;
}
public IAuthorizationService AuthorizationService => LazyGetRequiredService(typeof(IAuthorizationService), ref _authorizationService); public IAuthorizationService AuthorizationService => _lazyServiceProvider.LazyGetRequiredService<IAuthorizationService>();
private IAuthorizationService _authorizationService;
private IStringLocalizerFactory _stringLocalizerFactory; public IStringLocalizerFactory StringLocalizerFactory => _lazyServiceProvider.LazyGetRequiredService<IStringLocalizerFactory>();
public IStringLocalizerFactory StringLocalizerFactory => LazyGetRequiredService(typeof(IStringLocalizerFactory),ref _stringLocalizerFactory);
public ITheme Theme { get; } public ITheme Theme { get; }
@ -44,8 +28,9 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Toolbars
Theme = currentTheme; Theme = currentTheme;
Toolbar = toolbar; Toolbar = toolbar;
ServiceProvider = serviceProvider; ServiceProvider = serviceProvider;
_lazyServiceProvider = ServiceProvider.GetRequiredService<IAbpLazyServiceProvider>();
} }
public Task<bool> IsGrantedAsync(string policyName) public Task<bool> IsGrantedAsync(string policyName)
{ {
return AuthorizationService.IsGrantedAsync(policyName); return AuthorizationService.IsGrantedAsync(policyName);
@ -62,7 +47,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Toolbars
{ {
return StringLocalizerFactory.Create<T>(); return StringLocalizerFactory.Create<T>();
} }
[NotNull] [NotNull]
public IStringLocalizer GetLocalizer(Type resourceType) public IStringLocalizer GetLocalizer(Type resourceType)
{ {

87
framework/src/Volo.Abp.AspNetCore.Mvc.UI/Volo/Abp/AspNetCore/Mvc/UI/RazorPages/AbpPageModel.cs

@ -10,6 +10,7 @@ using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using Volo.Abp.AspNetCore.Mvc.UI.Alerts; using Volo.Abp.AspNetCore.Mvc.UI.Alerts;
using Volo.Abp.AspNetCore.Mvc.Validation; using Volo.Abp.AspNetCore.Mvc.Validation;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Guids; using Volo.Abp.Guids;
using Volo.Abp.Localization; using Volo.Abp.Localization;
using Volo.Abp.MultiTenancy; using Volo.Abp.MultiTenancy;
@ -24,67 +25,27 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.RazorPages
{ {
public abstract class AbpPageModel : PageModel public abstract class AbpPageModel : PageModel
{ {
public IServiceProvider ServiceProvider { get; set; } public IAbpLazyServiceProvider LazyServiceProvider { get; set; }
protected readonly object ServiceProviderLock = new object();
protected TService LazyGetRequiredService<TService>(ref TService reference)
=> LazyGetRequiredService(typeof(TService), ref reference);
protected TRef LazyGetRequiredService<TRef>(Type serviceType, ref TRef reference) public IServiceProvider ServiceProvider { get; set; }
{
if (reference == null)
{
lock (ServiceProviderLock)
{
if (reference == null)
{
reference = (TRef)ServiceProvider.GetRequiredService(serviceType);
}
}
}
return reference;
}
protected IClock Clock => LazyGetRequiredService(ref _clock); protected IClock Clock => LazyServiceProvider.LazyGetRequiredService<IClock>();
private IClock _clock;
protected AlertList Alerts => AlertManager.Alerts; protected AlertList Alerts => AlertManager.Alerts;
protected IUnitOfWorkManager UnitOfWorkManager => LazyGetRequiredService(ref _unitOfWorkManager); protected IUnitOfWorkManager UnitOfWorkManager => LazyServiceProvider.LazyGetRequiredService<IUnitOfWorkManager>();
private IUnitOfWorkManager _unitOfWorkManager;
protected Type ObjectMapperContext { get; set; } protected Type ObjectMapperContext { get; set; }
protected IObjectMapper ObjectMapper protected IObjectMapper ObjectMapper => LazyServiceProvider.LazyGetService<IObjectMapper>(provider =>
{ ObjectMapperContext == null
get ? provider.GetRequiredService<IObjectMapper>()
{ : (IObjectMapper) provider.GetRequiredService(typeof(IObjectMapper<>).MakeGenericType(ObjectMapperContext)));
if (_objectMapper != null)
{
return _objectMapper;
}
if (ObjectMapperContext == null)
{
return LazyGetRequiredService(ref _objectMapper);
}
return LazyGetRequiredService(
typeof(IObjectMapper<>).MakeGenericType(ObjectMapperContext),
ref _objectMapper
);
}
}
private IObjectMapper _objectMapper;
protected IGuidGenerator GuidGenerator => LazyGetRequiredService(ref _guidGenerator); protected IGuidGenerator GuidGenerator => LazyServiceProvider.LazyGetService<IGuidGenerator>(SimpleGuidGenerator.Instance);
private IGuidGenerator _guidGenerator;
protected ILoggerFactory LoggerFactory => LazyGetRequiredService(ref _loggerFactory); protected ILoggerFactory LoggerFactory => LazyServiceProvider.LazyGetRequiredService<ILoggerFactory>();
private ILoggerFactory _loggerFactory;
protected IStringLocalizerFactory StringLocalizerFactory => LazyGetRequiredService(ref _stringLocalizerFactory); protected IStringLocalizerFactory StringLocalizerFactory => LazyServiceProvider.LazyGetRequiredService<IStringLocalizerFactory>();
private IStringLocalizerFactory _stringLocalizerFactory;
protected IStringLocalizer L protected IStringLocalizer L
{ {
@ -103,31 +64,23 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.RazorPages
protected Type LocalizationResourceType { get; set; } protected Type LocalizationResourceType { get; set; }
protected ICurrentUser CurrentUser => LazyGetRequiredService(ref _currentUser); protected ICurrentUser CurrentUser => LazyServiceProvider.LazyGetRequiredService<ICurrentUser>();
private ICurrentUser _currentUser;
protected ICurrentTenant CurrentTenant => LazyGetRequiredService(ref _currentTenant); protected ICurrentTenant CurrentTenant => LazyServiceProvider.LazyGetRequiredService<ICurrentTenant>();
private ICurrentTenant _currentTenant;
protected ISettingProvider SettingProvider => LazyGetRequiredService(ref _settingProvider); protected ISettingProvider SettingProvider => LazyServiceProvider.LazyGetRequiredService<ISettingProvider>();
private ISettingProvider _settingProvider;
protected IModelStateValidator ModelValidator => LazyGetRequiredService(ref _modelValidator); protected IModelStateValidator ModelValidator => LazyServiceProvider.LazyGetRequiredService<IModelStateValidator>();
private IModelStateValidator _modelValidator;
protected IAuthorizationService AuthorizationService => LazyGetRequiredService(ref _authorizationService); protected IAuthorizationService AuthorizationService => LazyServiceProvider.LazyGetRequiredService<IAuthorizationService>();
private IAuthorizationService _authorizationService;
protected IAlertManager AlertManager => LazyGetRequiredService(ref _alertManager); protected IAlertManager AlertManager => LazyServiceProvider.LazyGetRequiredService<IAlertManager>();
private IAlertManager _alertManager;
protected IUnitOfWork CurrentUnitOfWork => UnitOfWorkManager?.Current; protected IUnitOfWork CurrentUnitOfWork => UnitOfWorkManager?.Current;
protected ILogger Logger => _lazyLogger.Value; protected ILogger Logger => LazyServiceProvider.LazyGetService<ILogger>(provider => LoggerFactory?.CreateLogger(GetType().FullName) ?? NullLogger.Instance);
private Lazy<ILogger> _lazyLogger => new Lazy<ILogger>(() => LoggerFactory?.CreateLogger(GetType().FullName) ?? NullLogger.Instance, true);
protected IAppUrlProvider AppUrlProvider => LazyGetRequiredService(ref _appUrlProvider); protected IAppUrlProvider AppUrlProvider => LazyServiceProvider.LazyGetRequiredService<IAppUrlProvider>();
private IAppUrlProvider _appUrlProvider;
protected virtual NoContentResult NoContent() //TODO: Is that true to return empty result like that? protected virtual NoContentResult NoContent() //TODO: Is that true to return empty result like that?
{ {

20
framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpActionContextExtensions.cs

@ -0,0 +1,20 @@
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.DependencyInjection;
namespace Volo.Abp.AspNetCore.Mvc
{
internal static class AbpActionContextExtensions
{
public static T GetRequiredService<T>(this FilterContext context)
where T : class
{
return context.HttpContext.RequestServices.GetRequiredService<T>();
}
public static T GetService<T>(this FilterContext context, T defaultValue = default)
where T : class
{
return context.HttpContext.RequestServices.GetService<T>() ?? defaultValue;
}
}
}

86
framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpController.cs

@ -8,6 +8,7 @@ using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Logging.Abstractions;
using Volo.Abp.Aspects; using Volo.Abp.Aspects;
using Volo.Abp.AspNetCore.Mvc.Validation; using Volo.Abp.AspNetCore.Mvc.Validation;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Features; using Volo.Abp.Features;
using Volo.Abp.Guids; using Volo.Abp.Guids;
using Volo.Abp.Localization; using Volo.Abp.Localization;
@ -22,85 +23,41 @@ namespace Volo.Abp.AspNetCore.Mvc
{ {
public abstract class AbpController : Controller, IAvoidDuplicateCrossCuttingConcerns public abstract class AbpController : Controller, IAvoidDuplicateCrossCuttingConcerns
{ {
public IServiceProvider ServiceProvider { get; set; } public IAbpLazyServiceProvider LazyServiceProvider { get; set; }
protected readonly object ServiceProviderLock = new object();
protected TService LazyGetRequiredService<TService>(ref TService reference)
=> LazyGetRequiredService(typeof(TService), ref reference);
protected TRef LazyGetRequiredService<TRef>(Type serviceType, ref TRef reference)
{
if (reference == null)
{
lock (ServiceProviderLock)
{
if (reference == null)
{
reference = (TRef)ServiceProvider.GetRequiredService(serviceType);
}
}
}
return reference; public IServiceProvider ServiceProvider { get; set; }
}
protected IUnitOfWorkManager UnitOfWorkManager => LazyGetRequiredService(ref _unitOfWorkManager); protected IUnitOfWorkManager UnitOfWorkManager => LazyServiceProvider.LazyGetRequiredService<IUnitOfWorkManager>();
private IUnitOfWorkManager _unitOfWorkManager;
protected Type ObjectMapperContext { get; set; } protected Type ObjectMapperContext { get; set; }
protected IObjectMapper ObjectMapper protected IObjectMapper ObjectMapper => LazyServiceProvider.LazyGetService<IObjectMapper>(provider =>
{ ObjectMapperContext == null
get ? provider.GetRequiredService<IObjectMapper>()
{ : (IObjectMapper) provider.GetRequiredService(typeof(IObjectMapper<>).MakeGenericType(ObjectMapperContext)));
if (_objectMapper != null)
{
return _objectMapper;
}
if (ObjectMapperContext == null) protected IGuidGenerator GuidGenerator => LazyServiceProvider.LazyGetService<IGuidGenerator>(SimpleGuidGenerator.Instance);
{
return LazyGetRequiredService(ref _objectMapper);
}
return LazyGetRequiredService( protected ILoggerFactory LoggerFactory => LazyServiceProvider.LazyGetRequiredService<ILoggerFactory>();
typeof(IObjectMapper<>).MakeGenericType(ObjectMapperContext),
ref _objectMapper
);
}
}
private IObjectMapper _objectMapper;
protected IGuidGenerator GuidGenerator => LazyGetRequiredService(ref _guidGenerator);
private IGuidGenerator _guidGenerator;
protected ILoggerFactory LoggerFactory => LazyGetRequiredService(ref _loggerFactory);
private ILoggerFactory _loggerFactory;
protected ILogger Logger => _lazyLogger.Value; protected ILogger Logger => LazyServiceProvider.LazyGetService<ILogger>(provider => LoggerFactory?.CreateLogger(GetType().FullName) ?? NullLogger.Instance);
private Lazy<ILogger> _lazyLogger => new Lazy<ILogger>(() => LoggerFactory?.CreateLogger(GetType().FullName) ?? NullLogger.Instance, true);
protected ICurrentUser CurrentUser => LazyGetRequiredService(ref _currentUser); protected ICurrentUser CurrentUser => LazyServiceProvider.LazyGetRequiredService<ICurrentUser>();
private ICurrentUser _currentUser;
protected ICurrentTenant CurrentTenant => LazyGetRequiredService(ref _currentTenant); protected ICurrentTenant CurrentTenant => LazyServiceProvider.LazyGetRequiredService<ICurrentTenant>();
private ICurrentTenant _currentTenant;
protected IAuthorizationService AuthorizationService => LazyGetRequiredService(ref _authorizationService); protected IAuthorizationService AuthorizationService => LazyServiceProvider.LazyGetRequiredService<IAuthorizationService>();
private IAuthorizationService _authorizationService;
protected IUnitOfWork CurrentUnitOfWork => UnitOfWorkManager?.Current; protected IUnitOfWork CurrentUnitOfWork => UnitOfWorkManager?.Current;
protected IClock Clock => LazyGetRequiredService(ref _clock); protected IClock Clock => LazyServiceProvider.LazyGetRequiredService<IClock>();
private IClock _clock;
protected IModelStateValidator ModelValidator => LazyGetRequiredService(ref _modelValidator); protected IModelStateValidator ModelValidator => LazyServiceProvider.LazyGetRequiredService<IModelStateValidator>();
private IModelStateValidator _modelValidator;
protected IFeatureChecker FeatureChecker => LazyGetRequiredService(ref _featureChecker); protected IFeatureChecker FeatureChecker => LazyServiceProvider.LazyGetRequiredService<IFeatureChecker>();
private IFeatureChecker _featureChecker;
protected IStringLocalizerFactory StringLocalizerFactory => LazyGetRequiredService(ref _stringLocalizerFactory); protected IAppUrlProvider AppUrlProvider => LazyServiceProvider.LazyGetRequiredService<IAppUrlProvider>();
private IStringLocalizerFactory _stringLocalizerFactory;
protected IStringLocalizerFactory StringLocalizerFactory => LazyServiceProvider.LazyGetRequiredService<IStringLocalizerFactory>();
protected IStringLocalizer L protected IStringLocalizer L
{ {
@ -116,9 +73,6 @@ namespace Volo.Abp.AspNetCore.Mvc
} }
private IStringLocalizer _localizer; private IStringLocalizer _localizer;
protected IAppUrlProvider AppUrlProvider => LazyGetRequiredService(ref _appUrlProvider);
private IAppUrlProvider _appUrlProvider;
protected Type LocalizationResource protected Type LocalizationResource
{ {
get => _localizationResource; get => _localizationResource;

47
framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpViewComponent.cs

@ -1,55 +1,22 @@
using System; using System;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.DependencyInjection;
using Volo.Abp.ObjectMapping; using Volo.Abp.ObjectMapping;
namespace Volo.Abp.AspNetCore.Mvc namespace Volo.Abp.AspNetCore.Mvc
{ {
public abstract class AbpViewComponent : ViewComponent public abstract class AbpViewComponent : ViewComponent
{ {
public IServiceProvider ServiceProvider { get; set; } public IAbpLazyServiceProvider LazyServiceProvider { get; set; }
protected readonly object ServiceProviderLock = new object();
protected TService LazyGetRequiredService<TService>(ref TService reference)
=> LazyGetRequiredService(typeof(TService), ref reference);
protected TRef LazyGetRequiredService<TRef>(Type serviceType, ref TRef reference)
{
if (reference == null)
{
lock (ServiceProviderLock)
{
if (reference == null)
{
reference = (TRef)ServiceProvider.GetRequiredService(serviceType);
}
}
}
return reference; public IServiceProvider ServiceProvider { get; set; }
}
protected Type ObjectMapperContext { get; set; } protected Type ObjectMapperContext { get; set; }
protected IObjectMapper ObjectMapper
{
get
{
if (_objectMapper != null)
{
return _objectMapper;
}
if (ObjectMapperContext == null)
{
return LazyGetRequiredService(ref _objectMapper);
}
return LazyGetRequiredService( protected IObjectMapper ObjectMapper => LazyServiceProvider.LazyGetService<IObjectMapper>(provider =>
typeof(IObjectMapper<>).MakeGenericType(ObjectMapperContext), ObjectMapperContext == null
ref _objectMapper ? provider.GetRequiredService<IObjectMapper>()
); : (IObjectMapper) provider.GetRequiredService(typeof(IObjectMapper<>).MakeGenericType(ObjectMapperContext)));
}
}
private IObjectMapper _objectMapper;
} }
} }

21
framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Auditing/AbpAuditActionFilter.cs

@ -12,17 +12,6 @@ namespace Volo.Abp.AspNetCore.Mvc.Auditing
{ {
public class AbpAuditActionFilter : IAsyncActionFilter, ITransientDependency public class AbpAuditActionFilter : IAsyncActionFilter, ITransientDependency
{ {
protected AbpAuditingOptions Options { get; }
private readonly IAuditingHelper _auditingHelper;
private readonly IAuditingManager _auditingManager;
public AbpAuditActionFilter(IOptions<AbpAuditingOptions> options, IAuditingHelper auditingHelper, IAuditingManager auditingManager)
{
Options = options.Value;
_auditingHelper = auditingHelper;
_auditingManager = auditingManager;
}
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{ {
if (!ShouldSaveAudit(context, out var auditLog, out var auditLogAction)) if (!ShouldSaveAudit(context, out var auditLog, out var auditLogAction))
@ -63,7 +52,8 @@ namespace Volo.Abp.AspNetCore.Mvc.Auditing
auditLog = null; auditLog = null;
auditLogAction = null; auditLogAction = null;
if (!Options.IsEnabled) var options = context.GetRequiredService<IOptions<AbpAuditingOptions>>().Value;
if (!options.IsEnabled)
{ {
return false; return false;
} }
@ -73,19 +63,20 @@ namespace Volo.Abp.AspNetCore.Mvc.Auditing
return false; return false;
} }
var auditLogScope = _auditingManager.Current; var auditLogScope = context.GetRequiredService<IAuditingManager>().Current;
if (auditLogScope == null) if (auditLogScope == null)
{ {
return false; return false;
} }
if (!_auditingHelper.ShouldSaveAudit(context.ActionDescriptor.GetMethodInfo(), true)) var auditingHelper = context.GetRequiredService<IAuditingHelper>();
if (!auditingHelper.ShouldSaveAudit(context.ActionDescriptor.GetMethodInfo(), true))
{ {
return false; return false;
} }
auditLog = auditLogScope.Log; auditLog = auditLogScope.Log;
auditLogAction = _auditingHelper.CreateAuditLogAction( auditLogAction = auditingHelper.CreateAuditLogAction(
auditLog, auditLog,
context.ActionDescriptor.AsControllerActionDescriptor().ControllerTypeInfo.AsType(), context.ActionDescriptor.AsControllerActionDescriptor().ControllerTypeInfo.AsType(),
context.ActionDescriptor.AsControllerActionDescriptor().MethodInfo, context.ActionDescriptor.AsControllerActionDescriptor().MethodInfo,

25
framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Auditing/AbpAuditPageFilter.cs

@ -12,22 +12,11 @@ namespace Volo.Abp.AspNetCore.Mvc.Auditing
{ {
public class AbpAuditPageFilter : IAsyncPageFilter, ITransientDependency public class AbpAuditPageFilter : IAsyncPageFilter, ITransientDependency
{ {
protected AbpAuditingOptions Options { get; }
private readonly IAuditingHelper _auditingHelper;
private readonly IAuditingManager _auditingManager;
public AbpAuditPageFilter(IOptions<AbpAuditingOptions> options, IAuditingHelper auditingHelper, IAuditingManager auditingManager)
{
Options = options.Value;
_auditingHelper = auditingHelper;
_auditingManager = auditingManager;
}
public Task OnPageHandlerSelectionAsync(PageHandlerSelectedContext context) public Task OnPageHandlerSelectionAsync(PageHandlerSelectedContext context)
{ {
return Task.CompletedTask; return Task.CompletedTask;
} }
public async Task OnPageHandlerExecutionAsync(PageHandlerExecutingContext context, PageHandlerExecutionDelegate next) public async Task OnPageHandlerExecutionAsync(PageHandlerExecutingContext context, PageHandlerExecutionDelegate next)
{ {
if (context.HandlerMethod == null || !ShouldSaveAudit(context, out var auditLog, out var auditLogAction)) if (context.HandlerMethod == null || !ShouldSaveAudit(context, out var auditLog, out var auditLogAction))
@ -68,7 +57,8 @@ namespace Volo.Abp.AspNetCore.Mvc.Auditing
auditLog = null; auditLog = null;
auditLogAction = null; auditLogAction = null;
if (!Options.IsEnabled) var options = context.GetRequiredService<IOptions<AbpAuditingOptions>>().Value;
if (!options.IsEnabled)
{ {
return false; return false;
} }
@ -78,19 +68,20 @@ namespace Volo.Abp.AspNetCore.Mvc.Auditing
return false; return false;
} }
var auditLogScope = _auditingManager.Current; var auditLogScope = context.GetRequiredService<IAuditingManager>().Current;
if (auditLogScope == null) if (auditLogScope == null)
{ {
return false; return false;
} }
if (!_auditingHelper.ShouldSaveAudit(context.HandlerMethod.MethodInfo, true)) var auditingHelper = context.GetRequiredService<IAuditingHelper>();
if (!auditingHelper.ShouldSaveAudit(context.HandlerMethod.MethodInfo, true))
{ {
return false; return false;
} }
auditLog = auditLogScope.Log; auditLog = auditLogScope.Log;
auditLogAction = _auditingHelper.CreateAuditLogAction( auditLogAction = auditingHelper.CreateAuditLogAction(
auditLog, auditLog,
context.HandlerMethod.GetType(), context.HandlerMethod.GetType(),
context.HandlerMethod.MethodInfo, context.HandlerMethod.MethodInfo,
@ -100,4 +91,4 @@ namespace Volo.Abp.AspNetCore.Mvc.Auditing
return true; return true;
} }
} }
} }

48
framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/AbpExceptionFilter.cs

@ -1,11 +1,10 @@
using System; using System;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Abstractions; using Microsoft.AspNetCore.Mvc.Abstractions;
using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
@ -19,27 +18,6 @@ namespace Volo.Abp.AspNetCore.Mvc.ExceptionHandling
{ {
public class AbpExceptionFilter : IAsyncExceptionFilter, ITransientDependency public class AbpExceptionFilter : IAsyncExceptionFilter, ITransientDependency
{ {
public ILogger<AbpExceptionFilter> Logger { get; set; }
private readonly IExceptionToErrorInfoConverter _errorInfoConverter;
private readonly IHttpExceptionStatusCodeFinder _statusCodeFinder;
private readonly IJsonSerializer _jsonSerializer;
private readonly AbpExceptionHandlingOptions _exceptionHandlingOptions;
public AbpExceptionFilter(
IExceptionToErrorInfoConverter errorInfoConverter,
IHttpExceptionStatusCodeFinder statusCodeFinder,
IJsonSerializer jsonSerializer,
IOptions<AbpExceptionHandlingOptions> exceptionHandlingOptions)
{
_errorInfoConverter = errorInfoConverter;
_statusCodeFinder = statusCodeFinder;
_jsonSerializer = jsonSerializer;
_exceptionHandlingOptions = exceptionHandlingOptions.Value;
Logger = NullLogger<AbpExceptionFilter>.Instance;
}
public async Task OnExceptionAsync(ExceptionContext context) public async Task OnExceptionAsync(ExceptionContext context)
{ {
if (!ShouldHandleException(context)) if (!ShouldHandleException(context))
@ -78,9 +56,13 @@ namespace Volo.Abp.AspNetCore.Mvc.ExceptionHandling
//TODO: Trigger an AbpExceptionHandled event or something like that. //TODO: Trigger an AbpExceptionHandled event or something like that.
context.HttpContext.Response.Headers.Add(AbpHttpConsts.AbpErrorFormat, "true"); context.HttpContext.Response.Headers.Add(AbpHttpConsts.AbpErrorFormat, "true");
context.HttpContext.Response.StatusCode = (int)_statusCodeFinder.GetStatusCode(context.HttpContext, context.Exception); context.HttpContext.Response.StatusCode = (int) context
.GetRequiredService<IHttpExceptionStatusCodeFinder>()
.GetStatusCode(context.HttpContext, context.Exception);
var remoteServiceErrorInfo = _errorInfoConverter.Convert(context.Exception, _exceptionHandlingOptions.SendExceptionsDetailsToClients); var exceptionHandlingOptions = context.GetRequiredService<IOptions<AbpExceptionHandlingOptions>>().Value;
var exceptionToErrorInfoConverter = context.GetRequiredService<IExceptionToErrorInfoConverter>();
var remoteServiceErrorInfo = exceptionToErrorInfoConverter.Convert(context.Exception, exceptionHandlingOptions.SendExceptionsDetailsToClients);
context.Result = new ObjectResult(new RemoteServiceErrorResponse(remoteServiceErrorInfo)); context.Result = new ObjectResult(new RemoteServiceErrorResponse(remoteServiceErrorInfo));
@ -88,17 +70,15 @@ namespace Volo.Abp.AspNetCore.Mvc.ExceptionHandling
var remoteServiceErrorInfoBuilder = new StringBuilder(); var remoteServiceErrorInfoBuilder = new StringBuilder();
remoteServiceErrorInfoBuilder.AppendLine($"---------- {nameof(RemoteServiceErrorInfo)} ----------"); remoteServiceErrorInfoBuilder.AppendLine($"---------- {nameof(RemoteServiceErrorInfo)} ----------");
remoteServiceErrorInfoBuilder.AppendLine( _jsonSerializer.Serialize(remoteServiceErrorInfo, indented: true)); remoteServiceErrorInfoBuilder.AppendLine(context.GetRequiredService<IJsonSerializer>().Serialize(remoteServiceErrorInfo, indented: true));
Logger.LogWithLevel(logLevel, remoteServiceErrorInfoBuilder.ToString());
var logger = context.GetService<ILogger<AbpExceptionFilter>>(NullLogger<AbpExceptionFilter>.Instance);
logger.LogWithLevel(logLevel, remoteServiceErrorInfoBuilder.ToString());
Logger.LogException(context.Exception, logLevel); logger.LogException(context.Exception, logLevel);
await context.HttpContext await context.GetRequiredService<IExceptionNotifier>().NotifyAsync(new ExceptionNotificationContext(context.Exception));
.RequestServices
.GetRequiredService<IExceptionNotifier>()
.NotifyAsync(
new ExceptionNotificationContext(context.Exception)
);
context.Exception = null; //Handled! context.Exception = null; //Handled!
} }

45
framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/AbpExceptionPageFilter.cs

@ -5,7 +5,6 @@ using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Abstractions; using Microsoft.AspNetCore.Mvc.Abstractions;
using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
@ -19,27 +18,6 @@ namespace Volo.Abp.AspNetCore.Mvc.ExceptionHandling
{ {
public class AbpExceptionPageFilter : IAsyncPageFilter, ITransientDependency public class AbpExceptionPageFilter : IAsyncPageFilter, ITransientDependency
{ {
public ILogger<AbpExceptionPageFilter> Logger { get; set; }
private readonly IExceptionToErrorInfoConverter _errorInfoConverter;
private readonly IHttpExceptionStatusCodeFinder _statusCodeFinder;
private readonly IJsonSerializer _jsonSerializer;
private readonly AbpExceptionHandlingOptions _exceptionHandlingOptions;
public AbpExceptionPageFilter(
IExceptionToErrorInfoConverter errorInfoConverter,
IHttpExceptionStatusCodeFinder statusCodeFinder,
IJsonSerializer jsonSerializer,
IOptions<AbpExceptionHandlingOptions> exceptionHandlingOptions)
{
_errorInfoConverter = errorInfoConverter;
_statusCodeFinder = statusCodeFinder;
_jsonSerializer = jsonSerializer;
_exceptionHandlingOptions = exceptionHandlingOptions.Value;
Logger = NullLogger<AbpExceptionPageFilter>.Instance;
}
public Task OnPageHandlerSelectionAsync(PageHandlerSelectedContext context) public Task OnPageHandlerSelectionAsync(PageHandlerSelectedContext context)
{ {
return Task.CompletedTask; return Task.CompletedTask;
@ -90,9 +68,13 @@ namespace Volo.Abp.AspNetCore.Mvc.ExceptionHandling
//TODO: Trigger an AbpExceptionHandled event or something like that. //TODO: Trigger an AbpExceptionHandled event or something like that.
context.HttpContext.Response.Headers.Add(AbpHttpConsts.AbpErrorFormat, "true"); context.HttpContext.Response.Headers.Add(AbpHttpConsts.AbpErrorFormat, "true");
context.HttpContext.Response.StatusCode = (int)_statusCodeFinder.GetStatusCode(context.HttpContext, context.Exception); context.HttpContext.Response.StatusCode = (int) context
.GetRequiredService<IHttpExceptionStatusCodeFinder>()
.GetStatusCode(context.HttpContext, context.Exception);
var remoteServiceErrorInfo = _errorInfoConverter.Convert(context.Exception, _exceptionHandlingOptions.SendExceptionsDetailsToClients); var exceptionHandlingOptions = context.GetRequiredService<IOptions<AbpExceptionHandlingOptions>>().Value;
var exceptionToErrorInfoConverter = context.GetRequiredService<IExceptionToErrorInfoConverter>();
var remoteServiceErrorInfo = exceptionToErrorInfoConverter.Convert(context.Exception, exceptionHandlingOptions.SendExceptionsDetailsToClients);
context.Result = new ObjectResult(new RemoteServiceErrorResponse(remoteServiceErrorInfo)); context.Result = new ObjectResult(new RemoteServiceErrorResponse(remoteServiceErrorInfo));
@ -100,17 +82,14 @@ namespace Volo.Abp.AspNetCore.Mvc.ExceptionHandling
var remoteServiceErrorInfoBuilder = new StringBuilder(); var remoteServiceErrorInfoBuilder = new StringBuilder();
remoteServiceErrorInfoBuilder.AppendLine($"---------- {nameof(RemoteServiceErrorInfo)} ----------"); remoteServiceErrorInfoBuilder.AppendLine($"---------- {nameof(RemoteServiceErrorInfo)} ----------");
remoteServiceErrorInfoBuilder.AppendLine( _jsonSerializer.Serialize(remoteServiceErrorInfo, indented: true)); remoteServiceErrorInfoBuilder.AppendLine(context.GetRequiredService<IJsonSerializer>().Serialize(remoteServiceErrorInfo, indented: true));
Logger.LogWithLevel(logLevel, remoteServiceErrorInfoBuilder.ToString());
var logger = context.GetService<ILogger<AbpExceptionFilter>>(NullLogger<AbpExceptionFilter>.Instance);
logger.LogWithLevel(logLevel, remoteServiceErrorInfoBuilder.ToString());
Logger.LogException(context.Exception, logLevel); logger.LogException(context.Exception, logLevel);
await context.HttpContext await context.GetRequiredService<IExceptionNotifier>().NotifyAsync(new ExceptionNotificationContext(context.Exception));
.RequestServices
.GetRequiredService<IExceptionNotifier>()
.NotifyAsync(
new ExceptionNotificationContext(context.Exception)
);
context.Exception = null; //Handled! context.Exception = null; //Handled!
} }

17
framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Features/AbpFeatureActionFilter.cs

@ -1,5 +1,4 @@
using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.AspNetCore.Mvc.Filters;
using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Abstractions; using Microsoft.AspNetCore.Mvc.Abstractions;
using Volo.Abp.Aspects; using Volo.Abp.Aspects;
@ -10,16 +9,7 @@ namespace Volo.Abp.AspNetCore.Mvc.Features
{ {
public class AbpFeatureActionFilter : IAsyncActionFilter, ITransientDependency public class AbpFeatureActionFilter : IAsyncActionFilter, ITransientDependency
{ {
private readonly IMethodInvocationFeatureCheckerService _methodInvocationAuthorizationService; public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
public AbpFeatureActionFilter(IMethodInvocationFeatureCheckerService methodInvocationAuthorizationService)
{
_methodInvocationAuthorizationService = methodInvocationAuthorizationService;
}
public async Task OnActionExecutionAsync(
ActionExecutingContext context,
ActionExecutionDelegate next)
{ {
if (!context.ActionDescriptor.IsControllerAction()) if (!context.ActionDescriptor.IsControllerAction())
{ {
@ -31,9 +21,8 @@ namespace Volo.Abp.AspNetCore.Mvc.Features
using (AbpCrossCuttingConcerns.Applying(context.Controller, AbpCrossCuttingConcerns.FeatureChecking)) using (AbpCrossCuttingConcerns.Applying(context.Controller, AbpCrossCuttingConcerns.FeatureChecking))
{ {
await _methodInvocationAuthorizationService.CheckAsync( var methodInvocationFeatureCheckerService = context.GetRequiredService<IMethodInvocationFeatureCheckerService>();
new MethodInvocationFeatureCheckerContext(methodInfo) await methodInvocationFeatureCheckerService.CheckAsync(new MethodInvocationFeatureCheckerContext(methodInfo));
);
await next(); await next();
} }

16
framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Features/AbpFeaturePageFilter.cs

@ -9,18 +9,11 @@ namespace Volo.Abp.AspNetCore.Mvc.Features
{ {
public class AbpFeaturePageFilter : IAsyncPageFilter, ITransientDependency public class AbpFeaturePageFilter : IAsyncPageFilter, ITransientDependency
{ {
private readonly IMethodInvocationFeatureCheckerService _methodInvocationAuthorizationService;
public AbpFeaturePageFilter(IMethodInvocationFeatureCheckerService methodInvocationAuthorizationService)
{
_methodInvocationAuthorizationService = methodInvocationAuthorizationService;
}
public Task OnPageHandlerSelectionAsync(PageHandlerSelectedContext context) public Task OnPageHandlerSelectionAsync(PageHandlerSelectedContext context)
{ {
return Task.CompletedTask; return Task.CompletedTask;
} }
public async Task OnPageHandlerExecutionAsync(PageHandlerExecutingContext context, PageHandlerExecutionDelegate next) public async Task OnPageHandlerExecutionAsync(PageHandlerExecutingContext context, PageHandlerExecutionDelegate next)
{ {
if (context.HandlerMethod == null || !context.ActionDescriptor.IsPageAction()) if (context.HandlerMethod == null || !context.ActionDescriptor.IsPageAction())
@ -33,12 +26,11 @@ namespace Volo.Abp.AspNetCore.Mvc.Features
using (AbpCrossCuttingConcerns.Applying(context.HandlerInstance, AbpCrossCuttingConcerns.FeatureChecking)) using (AbpCrossCuttingConcerns.Applying(context.HandlerInstance, AbpCrossCuttingConcerns.FeatureChecking))
{ {
await _methodInvocationAuthorizationService.CheckAsync( var methodInvocationFeatureCheckerService = context.GetRequiredService<IMethodInvocationFeatureCheckerService>();
new MethodInvocationFeatureCheckerContext(methodInfo) await methodInvocationFeatureCheckerService.CheckAsync(new MethodInvocationFeatureCheckerContext(methodInfo));
);
await next(); await next();
} }
} }
} }
} }

10
framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/GlobalFeatures/GlobalFeatureActionFilter.cs

@ -13,13 +13,6 @@ namespace Volo.Abp.AspNetCore.Mvc.GlobalFeatures
{ {
public class GlobalFeatureActionFilter : IAsyncActionFilter, ITransientDependency public class GlobalFeatureActionFilter : IAsyncActionFilter, ITransientDependency
{ {
public ILogger<GlobalFeatureActionFilter> Logger { get; set; }
public GlobalFeatureActionFilter()
{
Logger = NullLogger<GlobalFeatureActionFilter>.Instance;
}
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{ {
if (!context.ActionDescriptor.IsControllerAction()) if (!context.ActionDescriptor.IsControllerAction())
@ -30,7 +23,8 @@ namespace Volo.Abp.AspNetCore.Mvc.GlobalFeatures
if (!IsGlobalFeatureEnabled(context.Controller.GetType(), out var attribute)) if (!IsGlobalFeatureEnabled(context.Controller.GetType(), out var attribute))
{ {
Logger.LogWarning($"The '{context.Controller.GetType().FullName}' controller needs to enable '{attribute.Name}' feature."); var logger = context.GetService<ILogger<GlobalFeatureActionFilter>>(NullLogger<GlobalFeatureActionFilter>.Instance);
logger.LogWarning($"The '{context.Controller.GetType().FullName}' controller needs to enable '{attribute.Name}' feature.");
context.Result = new NotFoundResult(); context.Result = new NotFoundResult();
return; return;
} }

10
framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/GlobalFeatures/GlobalFeaturePageFilter.cs

@ -13,13 +13,6 @@ namespace Volo.Abp.AspNetCore.Mvc.GlobalFeatures
{ {
public class GlobalFeaturePageFilter: IAsyncPageFilter, ITransientDependency public class GlobalFeaturePageFilter: IAsyncPageFilter, ITransientDependency
{ {
public ILogger<GlobalFeaturePageFilter> Logger { get; set; }
public GlobalFeaturePageFilter()
{
Logger = NullLogger<GlobalFeaturePageFilter>.Instance;
}
public Task OnPageHandlerSelectionAsync(PageHandlerSelectedContext context) public Task OnPageHandlerSelectionAsync(PageHandlerSelectedContext context)
{ {
return Task.CompletedTask; return Task.CompletedTask;
@ -35,7 +28,8 @@ namespace Volo.Abp.AspNetCore.Mvc.GlobalFeatures
if (!IsGlobalFeatureEnabled(context.HandlerInstance.GetType(), out var attribute)) if (!IsGlobalFeatureEnabled(context.HandlerInstance.GetType(), out var attribute))
{ {
Logger.LogWarning($"The '{context.HandlerInstance.GetType().FullName}' page needs to enable '{attribute.Name}' feature."); var logger = context.GetService<ILogger<GlobalFeatureActionFilter>>(NullLogger<GlobalFeatureActionFilter>.Instance);
logger.LogWarning($"The '{context.HandlerInstance.GetType().FullName}' page needs to enable '{attribute.Name}' feature.");
context.Result = new NotFoundResult(); context.Result = new NotFoundResult();
return; return;
} }

15
framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpHybridJsonInputFormatter.cs

@ -8,8 +8,14 @@ namespace Volo.Abp.AspNetCore.Mvc.Json
{ {
public class AbpHybridJsonInputFormatter : TextInputFormatter, IInputFormatterExceptionPolicy public class AbpHybridJsonInputFormatter : TextInputFormatter, IInputFormatterExceptionPolicy
{ {
public AbpHybridJsonInputFormatter() private readonly SystemTextJsonInputFormatter _systemTextJsonInputFormatter;
private readonly NewtonsoftJsonInputFormatter _newtonsoftJsonInputFormatter;
public AbpHybridJsonInputFormatter(SystemTextJsonInputFormatter systemTextJsonInputFormatter, NewtonsoftJsonInputFormatter newtonsoftJsonInputFormatter)
{ {
_systemTextJsonInputFormatter = systemTextJsonInputFormatter;
_newtonsoftJsonInputFormatter = newtonsoftJsonInputFormatter;
SupportedEncodings.Add(UTF8EncodingWithoutBOM); SupportedEncodings.Add(UTF8EncodingWithoutBOM);
SupportedEncodings.Add(UTF16EncodingLittleEndian); SupportedEncodings.Add(UTF16EncodingLittleEndian);
@ -18,7 +24,7 @@ namespace Volo.Abp.AspNetCore.Mvc.Json
SupportedMediaTypes.Add(MediaTypeHeaderValues.ApplicationAnyJsonSyntax); SupportedMediaTypes.Add(MediaTypeHeaderValues.ApplicationAnyJsonSyntax);
} }
public async override Task<InputFormatterResult> ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding) public override async Task<InputFormatterResult> ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding)
{ {
return await GetTextInputFormatter(context).ReadRequestBodyAsync(context, encoding); return await GetTextInputFormatter(context).ReadRequestBodyAsync(context, encoding);
} }
@ -26,12 +32,13 @@ namespace Volo.Abp.AspNetCore.Mvc.Json
protected virtual TextInputFormatter GetTextInputFormatter(InputFormatterContext context) protected virtual TextInputFormatter GetTextInputFormatter(InputFormatterContext context)
{ {
var typesMatcher = context.HttpContext.RequestServices.GetRequiredService<AbpSystemTextJsonUnsupportedTypeMatcher>(); var typesMatcher = context.HttpContext.RequestServices.GetRequiredService<AbpSystemTextJsonUnsupportedTypeMatcher>();
if (!typesMatcher.Match(context.ModelType)) if (!typesMatcher.Match(context.ModelType))
{ {
return context.HttpContext.RequestServices.GetRequiredService<SystemTextJsonInputFormatter>(); return _systemTextJsonInputFormatter;
} }
return context.HttpContext.RequestServices.GetRequiredService<NewtonsoftJsonInputFormatter>(); return _newtonsoftJsonInputFormatter;
} }
public virtual InputFormatterExceptionPolicy ExceptionPolicy => InputFormatterExceptionPolicy.MalformedInputExceptions; public virtual InputFormatterExceptionPolicy ExceptionPolicy => InputFormatterExceptionPolicy.MalformedInputExceptions;

73
framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpHybridJsonOptionsSetup.cs

@ -0,0 +1,73 @@
using System.Buffers;
using System.Text.Encodings.Web;
using System.Text.Json;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Formatters;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.ObjectPool;
using Microsoft.Extensions.Options;
namespace Volo.Abp.AspNetCore.Mvc.Json
{
public class AbpHybridJsonOptionsSetup : IConfigureOptions<MvcOptions>
{
private readonly IOptions<JsonOptions> _jsonOptions;
private readonly IOptions<MvcNewtonsoftJsonOptions> _mvcNewtonsoftJsonOptions;
private readonly ILoggerFactory _loggerFactory;
private readonly ArrayPool<char> _charPool;
private readonly ObjectPoolProvider _objectPoolProvider;
public AbpHybridJsonOptionsSetup(
IOptions<JsonOptions> jsonOptions,
IOptions<MvcNewtonsoftJsonOptions> mvcNewtonsoftJsonOptions,
ILoggerFactory loggerFactory,
ArrayPool<char> charPool,
ObjectPoolProvider objectPoolProvider)
{
_jsonOptions = jsonOptions;
_mvcNewtonsoftJsonOptions = mvcNewtonsoftJsonOptions;
_loggerFactory = loggerFactory;
_charPool = charPool;
_objectPoolProvider = objectPoolProvider;
}
public void Configure(MvcOptions options)
{
var systemTextJsonInputFormatter = new SystemTextJsonInputFormatter(
_jsonOptions.Value,
_loggerFactory.CreateLogger<SystemTextJsonInputFormatter>());
var newtonsoftJsonInputFormatter = new NewtonsoftJsonInputFormatter(
_loggerFactory.CreateLogger<NewtonsoftJsonInputFormatter>(),
_mvcNewtonsoftJsonOptions.Value.SerializerSettings,
_charPool,
_objectPoolProvider,
options,
_mvcNewtonsoftJsonOptions.Value);
options.InputFormatters.RemoveType<SystemTextJsonInputFormatter>();
options.InputFormatters.RemoveType<NewtonsoftJsonInputFormatter>();
options.InputFormatters.Add(new AbpHybridJsonInputFormatter(systemTextJsonInputFormatter, newtonsoftJsonInputFormatter));
var jsonSerializerOptions = _jsonOptions.Value.JsonSerializerOptions;
if (jsonSerializerOptions.Encoder is null)
{
// If the user hasn't explicitly configured the encoder, use the less strict encoder that does not encode all non-ASCII characters.
jsonSerializerOptions = new JsonSerializerOptions(jsonSerializerOptions)
{
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
};
}
var systemTextJsonOutputFormatter = new SystemTextJsonOutputFormatter(jsonSerializerOptions);
var newtonsoftJsonOutputFormatter = new NewtonsoftJsonOutputFormatter(
_mvcNewtonsoftJsonOptions.Value.SerializerSettings,
_charPool,
options);
options.OutputFormatters.RemoveType<SystemTextJsonOutputFormatter>();
options.OutputFormatters.RemoveType<NewtonsoftJsonOutputFormatter>();
options.OutputFormatters.Add(new AbpHybridJsonOutputFormatter(systemTextJsonOutputFormatter, newtonsoftJsonOutputFormatter));
}
}
}

14
framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpHybridJsonOutputFormatter.cs

@ -8,8 +8,14 @@ namespace Volo.Abp.AspNetCore.Mvc.Json
{ {
public class AbpHybridJsonOutputFormatter : TextOutputFormatter public class AbpHybridJsonOutputFormatter : TextOutputFormatter
{ {
public AbpHybridJsonOutputFormatter() private readonly SystemTextJsonOutputFormatter _systemTextJsonOutputFormatter;
private readonly NewtonsoftJsonOutputFormatter _newtonsoftJsonOutputFormatter;
public AbpHybridJsonOutputFormatter(SystemTextJsonOutputFormatter systemTextJsonOutputFormatter, NewtonsoftJsonOutputFormatter newtonsoftJsonOutputFormatter)
{ {
_systemTextJsonOutputFormatter = systemTextJsonOutputFormatter;
_newtonsoftJsonOutputFormatter = newtonsoftJsonOutputFormatter;
SupportedEncodings.Add(Encoding.UTF8); SupportedEncodings.Add(Encoding.UTF8);
SupportedEncodings.Add(Encoding.Unicode); SupportedEncodings.Add(Encoding.Unicode);
@ -18,7 +24,7 @@ namespace Volo.Abp.AspNetCore.Mvc.Json
SupportedMediaTypes.Add(MediaTypeHeaderValues.ApplicationAnyJsonSyntax); SupportedMediaTypes.Add(MediaTypeHeaderValues.ApplicationAnyJsonSyntax);
} }
public async override Task WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding) public override async Task WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
{ {
await GetTextInputFormatter(context).WriteResponseBodyAsync(context, selectedEncoding); await GetTextInputFormatter(context).WriteResponseBodyAsync(context, selectedEncoding);
} }
@ -28,10 +34,10 @@ namespace Volo.Abp.AspNetCore.Mvc.Json
var typesMatcher = context.HttpContext.RequestServices.GetRequiredService<AbpSystemTextJsonUnsupportedTypeMatcher>(); var typesMatcher = context.HttpContext.RequestServices.GetRequiredService<AbpSystemTextJsonUnsupportedTypeMatcher>();
if (!typesMatcher.Match(context.ObjectType)) if (!typesMatcher.Match(context.ObjectType))
{ {
return context.HttpContext.RequestServices.GetRequiredService<SystemTextJsonOutputFormatter>(); return _systemTextJsonOutputFormatter;
} }
return context.HttpContext.RequestServices.GetRequiredService<NewtonsoftJsonOutputFormatter>(); return _newtonsoftJsonOutputFormatter;
} }
} }
} }

67
framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/MvcCoreBuilderExtensions.cs

@ -1,12 +1,7 @@
using System.Buffers; using Microsoft.AspNetCore.Mvc;
using System.Text.Json;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Formatters;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using System.Text.Encodings.Web;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.ObjectPool; using Microsoft.Extensions.ObjectPool;
using Volo.Abp.Json; using Volo.Abp.Json;
@ -24,68 +19,10 @@ namespace Volo.Abp.AspNetCore.Mvc.Json
return builder; return builder;
} }
//SystemTextJsonInputFormatter
builder.Services.AddTransient(provider =>
{
var jsonOptions = provider.GetRequiredService<IOptions<JsonOptions>>();
var logger = provider.GetRequiredService<ILoggerFactory>().CreateLogger<SystemTextJsonInputFormatter>();
return new SystemTextJsonInputFormatter(jsonOptions.Value, logger);
});
builder.Services.TryAddTransient<DefaultObjectPoolProvider>(); builder.Services.TryAddTransient<DefaultObjectPoolProvider>();
//NewtonsoftJsonInputFormatter
builder.Services.AddTransient(provider =>
{
var jsonOptions = provider.GetRequiredService<IOptions<MvcNewtonsoftJsonOptions>>().Value;
return new NewtonsoftJsonInputFormatter(
provider.GetRequiredService<ILoggerFactory>().CreateLogger<NewtonsoftJsonInputFormatter>(),
jsonOptions.SerializerSettings,
provider.GetRequiredService<ArrayPool<char>>(),
provider.GetRequiredService<DefaultObjectPoolProvider>(),
provider.GetRequiredService<IOptions<MvcOptions>>().Value,
jsonOptions);
});
//SystemTextJsonOutputFormatter
builder.Services.AddTransient(provider =>
{
var jsonSerializerOptions = provider.GetRequiredService<IOptions<JsonOptions>>().Value.JsonSerializerOptions;
if (jsonSerializerOptions.Encoder is null)
{
// If the user hasn't explicitly configured the encoder, use the less strict encoder that does not encode all non-ASCII characters.
jsonSerializerOptions = new JsonSerializerOptions(jsonSerializerOptions)
{
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
};
}
return new SystemTextJsonOutputFormatter(jsonSerializerOptions);
});
//NewtonsoftJsonOutputFormatter
builder.Services.AddTransient(provider =>
{
var jsonOptions = provider.GetRequiredService<IOptions<MvcNewtonsoftJsonOptions>>().Value;
return new NewtonsoftJsonOutputFormatter(
jsonOptions.SerializerSettings,
provider.GetRequiredService<ArrayPool<char>>(),
provider.GetRequiredService<IOptions<MvcOptions>>().Value);
});
builder.Services.TryAddEnumerable(ServiceDescriptor.Transient<IConfigureOptions<JsonOptions>, AbpJsonOptionsSetup>()); builder.Services.TryAddEnumerable(ServiceDescriptor.Transient<IConfigureOptions<JsonOptions>, AbpJsonOptionsSetup>());
builder.Services.TryAddEnumerable(ServiceDescriptor.Transient<IConfigureOptions<MvcNewtonsoftJsonOptions>, AbpMvcNewtonsoftJsonOptionsSetup>()); builder.Services.TryAddEnumerable(ServiceDescriptor.Transient<IConfigureOptions<MvcNewtonsoftJsonOptions>, AbpMvcNewtonsoftJsonOptionsSetup>());
builder.Services.TryAddEnumerable(ServiceDescriptor.Transient<IConfigureOptions<MvcOptions>, AbpHybridJsonOptionsSetup>());
builder.Services.Configure<MvcOptions>(options =>
{
options.InputFormatters.RemoveType<SystemTextJsonInputFormatter>();
options.InputFormatters.RemoveType<NewtonsoftJsonInputFormatter>();
options.InputFormatters.Add(new AbpHybridJsonInputFormatter());
options.OutputFormatters.RemoveType<SystemTextJsonOutputFormatter>();
options.OutputFormatters.RemoveType<NewtonsoftJsonOutputFormatter>();
options.OutputFormatters.Add(new AbpHybridJsonOutputFormatter());
});
return builder; return builder;
} }
} }

26
framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Uow/AbpUowActionFilter.cs

@ -1,4 +1,4 @@
using System; using System;
using System.Net.Http; using System.Net.Http;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Abstractions; using Microsoft.AspNetCore.Mvc.Abstractions;
@ -12,15 +12,6 @@ namespace Volo.Abp.AspNetCore.Mvc.Uow
{ {
public class AbpUowActionFilter : IAsyncActionFilter, ITransientDependency public class AbpUowActionFilter : IAsyncActionFilter, ITransientDependency
{ {
private readonly IUnitOfWorkManager _unitOfWorkManager;
private readonly AbpUnitOfWorkDefaultOptions _defaultOptions;
public AbpUowActionFilter(IUnitOfWorkManager unitOfWorkManager, IOptions<AbpUnitOfWorkDefaultOptions> options)
{
_unitOfWorkManager = unitOfWorkManager;
_defaultOptions = options.Value;
}
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{ {
if (!context.ActionDescriptor.IsControllerAction()) if (!context.ActionDescriptor.IsControllerAction())
@ -45,20 +36,22 @@ namespace Volo.Abp.AspNetCore.Mvc.Uow
var options = CreateOptions(context, unitOfWorkAttr); var options = CreateOptions(context, unitOfWorkAttr);
var unitOfWorkManager = context.GetRequiredService<IUnitOfWorkManager>();
//Trying to begin a reserved UOW by AbpUnitOfWorkMiddleware //Trying to begin a reserved UOW by AbpUnitOfWorkMiddleware
if (_unitOfWorkManager.TryBeginReserved(UnitOfWork.UnitOfWorkReservationName, options)) if (unitOfWorkManager.TryBeginReserved(UnitOfWork.UnitOfWorkReservationName, options))
{ {
var result = await next(); var result = await next();
if (!Succeed(result)) if (!Succeed(result))
{ {
await RollbackAsync(context); await RollbackAsync(context, unitOfWorkManager);
} }
return; return;
} }
//Begin a new, independent unit of work //Begin a new, independent unit of work
using (var uow = _unitOfWorkManager.Begin(options)) using (var uow = unitOfWorkManager.Begin(options))
{ {
var result = await next(); var result = await next();
if (Succeed(result)) if (Succeed(result))
@ -76,7 +69,8 @@ namespace Volo.Abp.AspNetCore.Mvc.Uow
if (unitOfWorkAttribute?.IsTransactional == null) if (unitOfWorkAttribute?.IsTransactional == null)
{ {
options.IsTransactional = _defaultOptions.CalculateIsTransactional( var abpUnitOfWorkDefaultOptions = context.GetRequiredService<IOptions<AbpUnitOfWorkDefaultOptions>>().Value;
options.IsTransactional = abpUnitOfWorkDefaultOptions.CalculateIsTransactional(
autoValue: !string.Equals(context.HttpContext.Request.Method, HttpMethod.Get.Method, StringComparison.OrdinalIgnoreCase) autoValue: !string.Equals(context.HttpContext.Request.Method, HttpMethod.Get.Method, StringComparison.OrdinalIgnoreCase)
); );
} }
@ -84,9 +78,9 @@ namespace Volo.Abp.AspNetCore.Mvc.Uow
return options; return options;
} }
private async Task RollbackAsync(ActionExecutingContext context) private async Task RollbackAsync(ActionExecutingContext context, IUnitOfWorkManager unitOfWorkManager)
{ {
var currentUow = _unitOfWorkManager.Current; var currentUow = unitOfWorkManager.Current;
if (currentUow != null) if (currentUow != null)
{ {
await currentUow.RollbackAsync(context.HttpContext.RequestAborted); await currentUow.RollbackAsync(context.HttpContext.RequestAborted);

25
framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Uow/AbpUowPageFilter.cs

@ -1,4 +1,4 @@
using System; using System;
using System.Net.Http; using System.Net.Http;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Abstractions; using Microsoft.AspNetCore.Mvc.Abstractions;
@ -12,14 +12,6 @@ namespace Volo.Abp.AspNetCore.Mvc.Uow
{ {
public class AbpUowPageFilter : IAsyncPageFilter, ITransientDependency public class AbpUowPageFilter : IAsyncPageFilter, ITransientDependency
{ {
private readonly IUnitOfWorkManager _unitOfWorkManager;
private readonly AbpUnitOfWorkDefaultOptions _defaultOptions;
public AbpUowPageFilter(IUnitOfWorkManager unitOfWorkManager, IOptions<AbpUnitOfWorkDefaultOptions> options)
{
_unitOfWorkManager = unitOfWorkManager;
_defaultOptions = options.Value;
}
public Task OnPageHandlerSelectionAsync(PageHandlerSelectedContext context) public Task OnPageHandlerSelectionAsync(PageHandlerSelectedContext context)
{ {
return Task.CompletedTask; return Task.CompletedTask;
@ -49,20 +41,22 @@ namespace Volo.Abp.AspNetCore.Mvc.Uow
var options = CreateOptions(context, unitOfWorkAttr); var options = CreateOptions(context, unitOfWorkAttr);
var unitOfWorkManager = context.GetRequiredService<IUnitOfWorkManager>();
//Trying to begin a reserved UOW by AbpUnitOfWorkMiddleware //Trying to begin a reserved UOW by AbpUnitOfWorkMiddleware
if (_unitOfWorkManager.TryBeginReserved(UnitOfWork.UnitOfWorkReservationName, options)) if (unitOfWorkManager.TryBeginReserved(UnitOfWork.UnitOfWorkReservationName, options))
{ {
var result = await next(); var result = await next();
if (!Succeed(result)) if (!Succeed(result))
{ {
await RollbackAsync(context); await RollbackAsync(context, unitOfWorkManager);
} }
return; return;
} }
//Begin a new, independent unit of work //Begin a new, independent unit of work
using (var uow = _unitOfWorkManager.Begin(options)) using (var uow = unitOfWorkManager.Begin(options))
{ {
var result = await next(); var result = await next();
if (Succeed(result)) if (Succeed(result))
@ -80,7 +74,8 @@ namespace Volo.Abp.AspNetCore.Mvc.Uow
if (unitOfWorkAttribute?.IsTransactional == null) if (unitOfWorkAttribute?.IsTransactional == null)
{ {
options.IsTransactional = _defaultOptions.CalculateIsTransactional( var abpUnitOfWorkDefaultOptions = context.GetRequiredService<IOptions<AbpUnitOfWorkDefaultOptions>>().Value;
options.IsTransactional = abpUnitOfWorkDefaultOptions.CalculateIsTransactional(
autoValue: !string.Equals(context.HttpContext.Request.Method, HttpMethod.Get.Method, StringComparison.OrdinalIgnoreCase) autoValue: !string.Equals(context.HttpContext.Request.Method, HttpMethod.Get.Method, StringComparison.OrdinalIgnoreCase)
); );
} }
@ -88,9 +83,9 @@ namespace Volo.Abp.AspNetCore.Mvc.Uow
return options; return options;
} }
private async Task RollbackAsync(PageHandlerExecutingContext context) private async Task RollbackAsync(PageHandlerExecutingContext context, IUnitOfWorkManager unitOfWorkManager)
{ {
var currentUow = _unitOfWorkManager.Current; var currentUow = unitOfWorkManager.Current;
if (currentUow != null) if (currentUow != null)
{ {
await currentUow.RollbackAsync(context.HttpContext.RequestAborted); await currentUow.RollbackAsync(context.HttpContext.RequestAborted);

9
framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Validation/AbpValidationActionFilter.cs

@ -7,13 +7,6 @@ namespace Volo.Abp.AspNetCore.Mvc.Validation
{ {
public class AbpValidationActionFilter : IAsyncActionFilter, ITransientDependency public class AbpValidationActionFilter : IAsyncActionFilter, ITransientDependency
{ {
private readonly IModelStateValidator _validator;
public AbpValidationActionFilter(IModelStateValidator validator)
{
_validator = validator;
}
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{ {
//TODO: Configuration to disable validation for controllers..? //TODO: Configuration to disable validation for controllers..?
@ -25,7 +18,7 @@ namespace Volo.Abp.AspNetCore.Mvc.Validation
return; return;
} }
_validator.Validate(context.ModelState); context.GetRequiredService<IModelStateValidator>().Validate(context.ModelState);
await next(); await next();
} }
} }

87
framework/src/Volo.Abp.AspNetCore.SignalR/Volo/Abp/AspNetCore/SignalR/AbpHub.cs

@ -5,6 +5,7 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Localization; using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Logging.Abstractions;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Localization; using Volo.Abp.Localization;
using Volo.Abp.MultiTenancy; using Volo.Abp.MultiTenancy;
using Volo.Abp.Timing; using Volo.Abp.Timing;
@ -14,48 +15,23 @@ namespace Volo.Abp.AspNetCore.SignalR
{ {
public abstract class AbpHub : Hub public abstract class AbpHub : Hub
{ {
public IServiceProvider ServiceProvider { get; set; } public IAbpLazyServiceProvider LazyServiceProvider { get; set; }
protected readonly object ServiceProviderLock = new object();
protected TService LazyGetRequiredService<TService>(ref TService reference)
=> LazyGetRequiredService(typeof(TService), ref reference);
protected TRef LazyGetRequiredService<TRef>(Type serviceType, ref TRef reference)
{
if (reference == null)
{
lock (ServiceProviderLock)
{
if (reference == null)
{
reference = (TRef)ServiceProvider.GetRequiredService(serviceType);
}
}
}
return reference; public IServiceProvider ServiceProvider { get; set; }
}
protected ILoggerFactory LoggerFactory => LazyGetRequiredService(ref _loggerFactory); protected ILoggerFactory LoggerFactory => LazyServiceProvider.LazyGetService<ILoggerFactory>();
private ILoggerFactory _loggerFactory;
protected ILogger Logger => _lazyLogger.Value; protected ILogger Logger => LazyServiceProvider.LazyGetService<ILogger>(provider => LoggerFactory?.CreateLogger(GetType().FullName) ?? NullLogger.Instance);
private Lazy<ILogger> _lazyLogger => new Lazy<ILogger>(() => LoggerFactory?.CreateLogger(GetType().FullName) ?? NullLogger.Instance, true);
protected ICurrentUser CurrentUser => LazyGetRequiredService(ref _currentUser); protected ICurrentUser CurrentUser => LazyServiceProvider.LazyGetService<ICurrentUser>();
private ICurrentUser _currentUser;
protected ICurrentTenant CurrentTenant => LazyGetRequiredService(ref _currentTenant); protected ICurrentTenant CurrentTenant => LazyServiceProvider.LazyGetService<ICurrentTenant>();
private ICurrentTenant _currentTenant;
protected IAuthorizationService AuthorizationService => LazyGetRequiredService(ref _authorizationService); protected IAuthorizationService AuthorizationService => LazyServiceProvider.LazyGetService<IAuthorizationService>();
private IAuthorizationService _authorizationService;
protected IClock Clock => LazyGetRequiredService(ref _clock); protected IClock Clock => LazyServiceProvider.LazyGetService<IClock>();
private IClock _clock;
protected IStringLocalizerFactory StringLocalizerFactory => LazyGetRequiredService(ref _stringLocalizerFactory); protected IStringLocalizerFactory StringLocalizerFactory => LazyServiceProvider.LazyGetService<IStringLocalizerFactory>();
private IStringLocalizerFactory _stringLocalizerFactory;
protected IStringLocalizer L protected IStringLocalizer L
{ {
@ -102,48 +78,23 @@ namespace Volo.Abp.AspNetCore.SignalR
public abstract class AbpHub<T> : Hub<T> public abstract class AbpHub<T> : Hub<T>
where T : class where T : class
{ {
public IServiceProvider ServiceProvider { get; set; } public IAbpLazyServiceProvider LazyServiceProvider { get; set; }
protected readonly object ServiceProviderLock = new object();
protected TService LazyGetRequiredService<TService>(ref TService reference)
=> LazyGetRequiredService(typeof(TService), ref reference);
protected TRef LazyGetRequiredService<TRef>(Type serviceType, ref TRef reference)
{
if (reference == null)
{
lock (ServiceProviderLock)
{
if (reference == null)
{
reference = (TRef)ServiceProvider.GetRequiredService(serviceType);
}
}
}
return reference; public IServiceProvider ServiceProvider { get; set; }
}
protected ILoggerFactory LoggerFactory => LazyGetRequiredService(ref _loggerFactory); protected ILoggerFactory LoggerFactory => LazyServiceProvider.LazyGetService<ILoggerFactory>();
private ILoggerFactory _loggerFactory;
protected ILogger Logger => _lazyLogger.Value; protected ILogger Logger => LazyServiceProvider.LazyGetService<ILogger>(provider => LoggerFactory?.CreateLogger(GetType().FullName) ?? NullLogger.Instance);
private Lazy<ILogger> _lazyLogger => new Lazy<ILogger>(() => LoggerFactory?.CreateLogger(GetType().FullName) ?? NullLogger.Instance, true);
protected ICurrentUser CurrentUser => LazyGetRequiredService(ref _currentUser); protected ICurrentUser CurrentUser => LazyServiceProvider.LazyGetService<ICurrentUser>();
private ICurrentUser _currentUser;
protected ICurrentTenant CurrentTenant => LazyGetRequiredService(ref _currentTenant); protected ICurrentTenant CurrentTenant => LazyServiceProvider.LazyGetService<ICurrentTenant>();
private ICurrentTenant _currentTenant;
protected IAuthorizationService AuthorizationService => LazyGetRequiredService(ref _authorizationService); protected IAuthorizationService AuthorizationService => LazyServiceProvider.LazyGetService<IAuthorizationService>();
private IAuthorizationService _authorizationService;
protected IClock Clock => LazyGetRequiredService(ref _clock); protected IClock Clock => LazyServiceProvider.LazyGetService<IClock>();
private IClock _clock;
protected IStringLocalizerFactory StringLocalizerFactory => LazyGetRequiredService(ref _stringLocalizerFactory); protected IStringLocalizerFactory StringLocalizerFactory => LazyServiceProvider.LazyGetService<IStringLocalizerFactory>();
private IStringLocalizerFactory _stringLocalizerFactory;
protected IStringLocalizer L protected IStringLocalizer L
{ {

48
framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditingInterceptor.cs

@ -1,6 +1,7 @@
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Aspects; using Volo.Abp.Aspects;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
using Volo.Abp.DynamicProxy; using Volo.Abp.DynamicProxy;
@ -9,16 +10,14 @@ namespace Volo.Abp.Auditing
{ {
public class AuditingInterceptor : AbpInterceptor, ITransientDependency public class AuditingInterceptor : AbpInterceptor, ITransientDependency
{ {
private readonly IAuditingHelper _auditingHelper; private readonly IServiceScopeFactory _serviceScopeFactory;
private readonly IAuditingManager _auditingManager;
public AuditingInterceptor(IAuditingHelper auditingHelper, IAuditingManager auditingManager) public AuditingInterceptor(IServiceScopeFactory serviceScopeFactory)
{ {
_auditingHelper = auditingHelper; _serviceScopeFactory = serviceScopeFactory;
_auditingManager = auditingManager;
} }
public async override Task InterceptAsync(IAbpMethodInvocation invocation) public override async Task InterceptAsync(IAbpMethodInvocation invocation)
{ {
if (!ShouldIntercept(invocation, out var auditLog, out var auditLogAction)) if (!ShouldIntercept(invocation, out var auditLog, out var auditLogAction))
{ {
@ -58,26 +57,31 @@ namespace Volo.Abp.Auditing
return false; return false;
} }
var auditLogScope = _auditingManager.Current; using (var scope = _serviceScopeFactory.CreateScope())
if (auditLogScope == null)
{ {
return false; var auditingManager = scope.ServiceProvider.GetRequiredService<IAuditingManager>();
} var auditLogScope = auditingManager.Current;
if (auditLogScope == null)
{
return false;
}
if (!_auditingHelper.ShouldSaveAudit(invocation.Method)) var auditingHelper = scope.ServiceProvider.GetRequiredService<IAuditingHelper>();
{ if (!auditingHelper.ShouldSaveAudit(invocation.Method))
return false; {
} return false;
}
auditLog = auditLogScope.Log; auditLog = auditLogScope.Log;
auditLogAction = _auditingHelper.CreateAuditLogAction( auditLogAction = auditingHelper.CreateAuditLogAction(
auditLog, auditLog,
invocation.TargetObject.GetType(), invocation.TargetObject.GetType(),
invocation.Method, invocation.Method,
invocation.Arguments invocation.Arguments
); );
return true; return true;
}
} }
} }
} }

2
framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AuthorizationInterceptor.cs

@ -13,7 +13,7 @@ namespace Volo.Abp.Authorization
_methodInvocationAuthorizationService = methodInvocationAuthorizationService; _methodInvocationAuthorizationService = methodInvocationAuthorizationService;
} }
public async override Task InterceptAsync(IAbpMethodInvocation invocation) public override async Task InterceptAsync(IAbpMethodInvocation invocation)
{ {
await AuthorizeAsync(invocation); await AuthorizeAsync(invocation);
await invocation.ProceedAsync(); await invocation.ProceedAsync();

22
framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/MethodInvocationAuthorizationService.cs

@ -1,23 +1,21 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
namespace Volo.Abp.Authorization namespace Volo.Abp.Authorization
{ {
public class MethodInvocationAuthorizationService : IMethodInvocationAuthorizationService, ITransientDependency public class MethodInvocationAuthorizationService : IMethodInvocationAuthorizationService, ITransientDependency
{ {
private readonly IAbpAuthorizationPolicyProvider _abpAuthorizationPolicyProvider; private readonly IServiceProvider _serviceProvider;
private readonly IAbpAuthorizationService _abpAuthorizationService;
public MethodInvocationAuthorizationService( public MethodInvocationAuthorizationService(IServiceProvider serviceProvider)
IAbpAuthorizationPolicyProvider abpAuthorizationPolicyProvider,
IAbpAuthorizationService abpAuthorizationService)
{ {
_abpAuthorizationPolicyProvider = abpAuthorizationPolicyProvider; _serviceProvider = serviceProvider;
_abpAuthorizationService = abpAuthorizationService;
} }
public async Task CheckAsync(MethodInvocationAuthorizationContext context) public async Task CheckAsync(MethodInvocationAuthorizationContext context)
@ -28,7 +26,7 @@ namespace Volo.Abp.Authorization
} }
var authorizationPolicy = await AuthorizationPolicy.CombineAsync( var authorizationPolicy = await AuthorizationPolicy.CombineAsync(
_abpAuthorizationPolicyProvider, _serviceProvider.GetRequiredService<IAbpAuthorizationPolicyProvider>(),
GetAuthorizationDataAttributes(context.Method) GetAuthorizationDataAttributes(context.Method)
); );
@ -36,8 +34,8 @@ namespace Volo.Abp.Authorization
{ {
return; return;
} }
await _abpAuthorizationService.CheckAsync(authorizationPolicy); await _serviceProvider.GetRequiredService<IAbpAuthorizationService>().CheckAsync(authorizationPolicy);
} }
protected virtual bool AllowAnonymous(MethodInvocationAuthorizationContext context) protected virtual bool AllowAnonymous(MethodInvocationAuthorizationContext context)
@ -64,4 +62,4 @@ namespace Volo.Abp.Authorization
return attributes; return attributes;
} }
} }
} }

29
framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/BackgroundWorkerBase.cs

@ -1,9 +1,9 @@
using System; using System;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Logging.Abstractions;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.BackgroundWorkers namespace Volo.Abp.BackgroundWorkers
{ {
@ -13,33 +13,14 @@ namespace Volo.Abp.BackgroundWorkers
public abstract class BackgroundWorkerBase : IBackgroundWorker public abstract class BackgroundWorkerBase : IBackgroundWorker
{ {
//TODO: Add UOW, Localization and other useful properties..? //TODO: Add UOW, Localization and other useful properties..?
public IServiceProvider ServiceProvider { get; set; }
protected readonly object ServiceProviderLock = new object();
protected TService LazyGetRequiredService<TService>(ref TService reference) public IAbpLazyServiceProvider LazyServiceProvider { get; set; }
=> LazyGetRequiredService(typeof(TService), ref reference);
protected TRef LazyGetRequiredService<TRef>(Type serviceType, ref TRef reference) public IServiceProvider ServiceProvider { get; set; }
{
if (reference == null)
{
lock (ServiceProviderLock)
{
if (reference == null)
{
reference = (TRef)ServiceProvider.GetRequiredService(serviceType);
}
}
}
return reference;
}
protected ILoggerFactory LoggerFactory => LazyGetRequiredService(ref _loggerFactory); protected ILoggerFactory LoggerFactory => LazyServiceProvider.LazyGetRequiredService<ILoggerFactory>();
private ILoggerFactory _loggerFactory;
protected ILogger Logger => _lazyLogger.Value; protected ILogger Logger => LazyServiceProvider.LazyGetService<ILogger>(provider => LoggerFactory?.CreateLogger(GetType().FullName) ?? NullLogger.Instance);
private Lazy<ILogger> _lazyLogger => new Lazy<ILogger>(() => LoggerFactory?.CreateLogger(GetType().FullName) ?? NullLogger.Instance, true);
public virtual Task StartAsync(CancellationToken cancellationToken = default) public virtual Task StartAsync(CancellationToken cancellationToken = default)
{ {

59
framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/AbpLazyServiceProvider.cs

@ -0,0 +1,59 @@
using System;
using System.Collections.Generic;
using Microsoft.Extensions.DependencyInjection;
namespace Volo.Abp.DependencyInjection
{
public class AbpLazyServiceProvider : IAbpLazyServiceProvider, ITransientDependency
{
protected IDictionary<Type, object> CachedServices { get; set; }
protected IServiceProvider ServiceProvider { get; set; }
public AbpLazyServiceProvider(IServiceProvider serviceProvider)
{
ServiceProvider = serviceProvider;
CachedServices = new Dictionary<Type, object>();
}
public virtual T LazyGetRequiredService<T>()
{
return (T) LazyGetRequiredService(typeof(T));
}
public virtual object LazyGetRequiredService(Type serviceType)
{
return CachedServices.GetOrAdd(serviceType, () => ServiceProvider.GetRequiredService(serviceType));
}
public virtual T LazyGetService<T>()
{
return (T) LazyGetService(typeof(T));
}
public virtual object LazyGetService(Type serviceType)
{
return CachedServices.GetOrAdd(serviceType, () => ServiceProvider.GetService(serviceType));
}
public virtual T LazyGetService<T>(T defaultValue)
{
return (T) LazyGetService(typeof(T), defaultValue);
}
public virtual object LazyGetService(Type serviceType, object defaultValue)
{
return LazyGetService(serviceType) ?? defaultValue;
}
public virtual T LazyGetService<T>(Func<IServiceProvider, object> factory)
{
return (T) LazyGetService(typeof(T), factory);
}
public virtual object LazyGetService(Type serviceType, Func<IServiceProvider, object> factory)
{
return CachedServices.GetOrAdd(serviceType, () => factory(ServiceProvider));
}
}
}

23
framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/IAbpLazyServiceProvider.cs

@ -0,0 +1,23 @@
using System;
namespace Volo.Abp.DependencyInjection
{
public interface IAbpLazyServiceProvider
{
T LazyGetRequiredService<T>();
object LazyGetRequiredService(Type serviceType);
T LazyGetService<T>();
object LazyGetService(Type serviceType);
T LazyGetService<T>(T defaultValue);
object LazyGetService(Type serviceType, object defaultValue);
object LazyGetService(Type serviceType, Func<IServiceProvider, object> factory);
T LazyGetService<T>(Func<IServiceProvider, object> factory);
}
}

89
framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/ApplicationService.cs

@ -33,86 +33,41 @@ namespace Volo.Abp.Application.Services
IAuditingEnabled, IAuditingEnabled,
ITransientDependency ITransientDependency
{ {
public IServiceProvider ServiceProvider { get; set; } public IAbpLazyServiceProvider LazyServiceProvider { get; set; }
protected readonly object ServiceProviderLock = new object();
protected TService LazyGetRequiredService<TService>(ref TService reference)
=> LazyGetRequiredService(typeof(TService), ref reference);
protected TRef LazyGetRequiredService<TRef>(Type serviceType, ref TRef reference) public IServiceProvider ServiceProvider { get; set; }
{
if (reference == null)
{
lock (ServiceProviderLock)
{
if (reference == null)
{
reference = (TRef)ServiceProvider.GetRequiredService(serviceType);
}
}
}
return reference;
}
public static string[] CommonPostfixes { get; set; } = { "AppService", "ApplicationService", "Service" }; public static string[] CommonPostfixes { get; set; } = { "AppService", "ApplicationService", "Service" };
public List<string> AppliedCrossCuttingConcerns { get; } = new List<string>(); public List<string> AppliedCrossCuttingConcerns { get; } = new List<string>();
protected IUnitOfWorkManager UnitOfWorkManager => LazyGetRequiredService(ref _unitOfWorkManager); protected IUnitOfWorkManager UnitOfWorkManager => LazyServiceProvider.LazyGetRequiredService<IUnitOfWorkManager>();
private IUnitOfWorkManager _unitOfWorkManager;
protected IAsyncQueryableExecuter AsyncExecuter => LazyGetRequiredService(ref _asyncExecuter);
private IAsyncQueryableExecuter _asyncExecuter;
protected Type ObjectMapperContext { get; set; } protected IAsyncQueryableExecuter AsyncExecuter => LazyServiceProvider.LazyGetRequiredService<IAsyncQueryableExecuter>();
protected IObjectMapper ObjectMapper
{
get
{
if (_objectMapper != null)
{
return _objectMapper;
}
if (ObjectMapperContext == null)
{
return LazyGetRequiredService(ref _objectMapper);
}
return LazyGetRequiredService( protected Type ObjectMapperContext { get; set; }
typeof(IObjectMapper<>).MakeGenericType(ObjectMapperContext), protected IObjectMapper ObjectMapper => LazyServiceProvider.LazyGetService<IObjectMapper>(provider =>
ref _objectMapper ObjectMapperContext == null
); ? provider.GetRequiredService<IObjectMapper>()
} : (IObjectMapper) provider.GetRequiredService(typeof(IObjectMapper<>).MakeGenericType(ObjectMapperContext)));
}
private IObjectMapper _objectMapper;
public IGuidGenerator GuidGenerator { get; set; } public IGuidGenerator GuidGenerator => LazyServiceProvider.LazyGetService<IGuidGenerator>(SimpleGuidGenerator.Instance);
protected ILoggerFactory LoggerFactory => LazyGetRequiredService(ref _loggerFactory); protected ILoggerFactory LoggerFactory => LazyServiceProvider.LazyGetRequiredService<ILoggerFactory>();
private ILoggerFactory _loggerFactory;
protected ICurrentTenant CurrentTenant => LazyGetRequiredService(ref _currentTenant); protected ICurrentTenant CurrentTenant => LazyServiceProvider.LazyGetRequiredService<ICurrentTenant>();
private ICurrentTenant _currentTenant;
protected ICurrentUser CurrentUser => LazyGetRequiredService(ref _currentUser); protected ICurrentUser CurrentUser => LazyServiceProvider.LazyGetRequiredService<ICurrentUser>();
private ICurrentUser _currentUser;
protected ISettingProvider SettingProvider => LazyGetRequiredService(ref _settingProvider); protected ISettingProvider SettingProvider => LazyServiceProvider.LazyGetRequiredService<ISettingProvider>();
private ISettingProvider _settingProvider;
protected IClock Clock => LazyGetRequiredService(ref _clock); protected IClock Clock => LazyServiceProvider.LazyGetRequiredService<IClock>();
private IClock _clock;
protected IAuthorizationService AuthorizationService => LazyGetRequiredService(ref _authorizationService); protected IAuthorizationService AuthorizationService => LazyServiceProvider.LazyGetRequiredService<IAuthorizationService>();
private IAuthorizationService _authorizationService;
protected IFeatureChecker FeatureChecker => LazyGetRequiredService(ref _featureChecker); protected IFeatureChecker FeatureChecker => LazyServiceProvider.LazyGetRequiredService<IFeatureChecker>();
private IFeatureChecker _featureChecker;
protected IStringLocalizerFactory StringLocalizerFactory => LazyGetRequiredService(ref _stringLocalizerFactory); protected IStringLocalizerFactory StringLocalizerFactory => LazyServiceProvider.LazyGetRequiredService<IStringLocalizerFactory>();
private IStringLocalizerFactory _stringLocalizerFactory;
protected IStringLocalizer L protected IStringLocalizer L
{ {
@ -141,13 +96,7 @@ namespace Volo.Abp.Application.Services
protected IUnitOfWork CurrentUnitOfWork => UnitOfWorkManager?.Current; protected IUnitOfWork CurrentUnitOfWork => UnitOfWorkManager?.Current;
protected ILogger Logger => _lazyLogger.Value; protected ILogger Logger => LazyServiceProvider.LazyGetService<ILogger>(provider => LoggerFactory?.CreateLogger(GetType().FullName) ?? NullLogger.Instance);
private Lazy<ILogger> _lazyLogger => new Lazy<ILogger>(() => LoggerFactory?.CreateLogger(GetType().FullName) ?? NullLogger.Instance, true);
protected ApplicationService()
{
GuidGenerator = SimpleGuidGenerator.Instance;
}
/// <summary> /// <summary>
/// Checks for given <paramref name="policyName"/>. /// Checks for given <paramref name="policyName"/>.

14
framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/BasicRepositoryBase.cs

@ -19,21 +19,23 @@ namespace Volo.Abp.Domain.Repositories
IUnitOfWorkEnabled IUnitOfWorkEnabled
where TEntity : class, IEntity where TEntity : class, IEntity
{ {
public IAbpLazyServiceProvider LazyServiceProvider { get; set; }
public IServiceProvider ServiceProvider { get; set; } public IServiceProvider ServiceProvider { get; set; }
public IDataFilter DataFilter { get; set; } public IDataFilter DataFilter => LazyServiceProvider.LazyGetRequiredService<IDataFilter>();
public ICurrentTenant CurrentTenant { get; set; } public ICurrentTenant CurrentTenant => LazyServiceProvider.LazyGetRequiredService<ICurrentTenant>();
public IAsyncQueryableExecuter AsyncExecuter { get; set; } public IAsyncQueryableExecuter AsyncExecuter => LazyServiceProvider.LazyGetRequiredService<IAsyncQueryableExecuter>();
public IUnitOfWorkManager UnitOfWorkManager { get; set; } public IUnitOfWorkManager UnitOfWorkManager => LazyServiceProvider.LazyGetRequiredService<IUnitOfWorkManager>();
public ICancellationTokenProvider CancellationTokenProvider { get; set; } public ICancellationTokenProvider CancellationTokenProvider => LazyServiceProvider.LazyGetService<ICancellationTokenProvider>(NullCancellationTokenProvider.Instance);
protected BasicRepositoryBase() protected BasicRepositoryBase()
{ {
CancellationTokenProvider = NullCancellationTokenProvider.Instance;
} }
public abstract Task<TEntity> InsertAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default); public abstract Task<TEntity> InsertAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default);

2
framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/RepositoryBase.cs

@ -6,9 +6,7 @@ using System.Linq;
using System.Linq.Expressions; using System.Linq.Expressions;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Volo.Abp.Data;
using Volo.Abp.Domain.Entities; using Volo.Abp.Domain.Entities;
using Volo.Abp.Linq;
using Volo.Abp.MultiTenancy; using Volo.Abp.MultiTenancy;
using Volo.Abp.Uow; using Volo.Abp.Uow;

54
framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Services/DomainService.cs

@ -1,7 +1,7 @@
using System; using System;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Logging.Abstractions;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Guids; using Volo.Abp.Guids;
using Volo.Abp.Linq; using Volo.Abp.Linq;
using Volo.Abp.MultiTenancy; using Volo.Abp.MultiTenancy;
@ -11,44 +11,20 @@ namespace Volo.Abp.Domain.Services
{ {
public abstract class DomainService : IDomainService public abstract class DomainService : IDomainService
{ {
public IAbpLazyServiceProvider LazyServiceProvider { get; set; }
public IServiceProvider ServiceProvider { get; set; } public IServiceProvider ServiceProvider { get; set; }
protected readonly object ServiceProviderLock = new object();
protected TService LazyGetRequiredService<TService>(ref TService reference) protected IClock Clock => LazyServiceProvider.LazyGetRequiredService<IClock>();
{
if (reference == null) public IGuidGenerator GuidGenerator => LazyServiceProvider.LazyGetService<IGuidGenerator>(SimpleGuidGenerator.Instance);
{
lock (ServiceProviderLock) protected ILoggerFactory LoggerFactory => LazyServiceProvider.LazyGetRequiredService<ILoggerFactory>();
{
if (reference == null) protected ICurrentTenant CurrentTenant => LazyServiceProvider.LazyGetRequiredService<ICurrentTenant>();
{
reference = ServiceProvider.GetRequiredService<TService>(); protected IAsyncQueryableExecuter AsyncExecuter => LazyServiceProvider.LazyGetRequiredService<IAsyncQueryableExecuter>();
}
} protected ILogger Logger => LazyServiceProvider.LazyGetService<ILogger>(provider => LoggerFactory?.CreateLogger(GetType().FullName) ?? NullLogger.Instance);
}
return reference;
}
protected IClock Clock => LazyGetRequiredService(ref _clock);
private IClock _clock;
public IGuidGenerator GuidGenerator { get; set; }
protected ILoggerFactory LoggerFactory => LazyGetRequiredService(ref _loggerFactory);
private ILoggerFactory _loggerFactory;
protected ICurrentTenant CurrentTenant => LazyGetRequiredService(ref _currentTenant);
private ICurrentTenant _currentTenant;
protected IAsyncQueryableExecuter AsyncExecuter => LazyGetRequiredService(ref _asyncExecuter);
private IAsyncQueryableExecuter _asyncExecuter;
protected ILogger Logger => _lazyLogger.Value;
private Lazy<ILogger> _lazyLogger => new Lazy<ILogger>(() => LoggerFactory?.CreateLogger(GetType().FullName) ?? NullLogger.Instance, true);
protected DomainService()
{
GuidGenerator = SimpleGuidGenerator.Instance;
}
} }
} }

12
framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Domain/Repositories/EntityFrameworkCore/EfCoreRepository.cs

@ -1,4 +1,5 @@
using Microsoft.EntityFrameworkCore; using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using System; using System;
@ -53,14 +54,13 @@ namespace Volo.Abp.Domain.Repositories.EntityFrameworkCore
private readonly IDbContextProvider<TDbContext> _dbContextProvider; private readonly IDbContextProvider<TDbContext> _dbContextProvider;
private readonly Lazy<AbpEntityOptions<TEntity>> _entityOptionsLazy; private readonly Lazy<AbpEntityOptions<TEntity>> _entityOptionsLazy;
public IGuidGenerator GuidGenerator { get; set; } public virtual IGuidGenerator GuidGenerator => LazyServiceProvider.LazyGetService<IGuidGenerator>(SimpleGuidGenerator.Instance);
public IEfCoreBulkOperationProvider BulkOperationProvider { get; set; } public IEfCoreBulkOperationProvider BulkOperationProvider => LazyServiceProvider.LazyGetService<IEfCoreBulkOperationProvider>();
public EfCoreRepository(IDbContextProvider<TDbContext> dbContextProvider) public EfCoreRepository(IDbContextProvider<TDbContext> dbContextProvider)
{ {
_dbContextProvider = dbContextProvider; _dbContextProvider = dbContextProvider;
GuidGenerator = SimpleGuidGenerator.Instance;
_entityOptionsLazy = new Lazy<AbpEntityOptions<TEntity>>( _entityOptionsLazy = new Lazy<AbpEntityOptions<TEntity>>(
() => ServiceProvider () => ServiceProvider
@ -103,7 +103,7 @@ namespace Volo.Abp.Domain.Repositories.EntityFrameworkCore
this, this,
entityArray, entityArray,
autoSave, autoSave,
cancellationToken GetCancellationToken(cancellationToken)
); );
return; return;
} }
@ -142,7 +142,7 @@ namespace Volo.Abp.Domain.Repositories.EntityFrameworkCore
this, this,
entities, entities,
autoSave, autoSave,
cancellationToken GetCancellationToken(cancellationToken)
); );
return; return;

30
framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs

@ -23,7 +23,6 @@ using Volo.Abp.EntityFrameworkCore.EntityHistory;
using Volo.Abp.EntityFrameworkCore.Modeling; using Volo.Abp.EntityFrameworkCore.Modeling;
using Volo.Abp.EntityFrameworkCore.ValueConverters; using Volo.Abp.EntityFrameworkCore.ValueConverters;
using Volo.Abp.Guids; using Volo.Abp.Guids;
using Volo.Abp.Localization;
using Volo.Abp.MultiTenancy; using Volo.Abp.MultiTenancy;
using Volo.Abp.ObjectExtending; using Volo.Abp.ObjectExtending;
using Volo.Abp.Reflection; using Volo.Abp.Reflection;
@ -35,31 +34,33 @@ namespace Volo.Abp.EntityFrameworkCore
public abstract class AbpDbContext<TDbContext> : DbContext, IAbpEfCoreDbContext, ITransientDependency public abstract class AbpDbContext<TDbContext> : DbContext, IAbpEfCoreDbContext, ITransientDependency
where TDbContext : DbContext where TDbContext : DbContext
{ {
public IAbpLazyServiceProvider LazyServiceProvider { get; set; }
protected virtual Guid? CurrentTenantId => CurrentTenant?.Id; protected virtual Guid? CurrentTenantId => CurrentTenant?.Id;
protected virtual bool IsMultiTenantFilterEnabled => DataFilter?.IsEnabled<IMultiTenant>() ?? false; protected virtual bool IsMultiTenantFilterEnabled => DataFilter?.IsEnabled<IMultiTenant>() ?? false;
protected virtual bool IsSoftDeleteFilterEnabled => DataFilter?.IsEnabled<ISoftDelete>() ?? false; protected virtual bool IsSoftDeleteFilterEnabled => DataFilter?.IsEnabled<ISoftDelete>() ?? false;
public ICurrentTenant CurrentTenant { get; set; } public ICurrentTenant CurrentTenant => LazyServiceProvider.LazyGetRequiredService<ICurrentTenant>();
public IGuidGenerator GuidGenerator { get; set; } public IGuidGenerator GuidGenerator => LazyServiceProvider.LazyGetService<IGuidGenerator>(SimpleGuidGenerator.Instance);
public IDataFilter DataFilter { get; set; } public IDataFilter DataFilter => LazyServiceProvider.LazyGetRequiredService<IDataFilter>();
public IEntityChangeEventHelper EntityChangeEventHelper { get; set; } public IEntityChangeEventHelper EntityChangeEventHelper => LazyServiceProvider.LazyGetService<IEntityChangeEventHelper>(NullEntityChangeEventHelper.Instance);
public IAuditPropertySetter AuditPropertySetter { get; set; } public IAuditPropertySetter AuditPropertySetter => LazyServiceProvider.LazyGetRequiredService<IAuditPropertySetter>();
public IEntityHistoryHelper EntityHistoryHelper { get; set; } public IEntityHistoryHelper EntityHistoryHelper => LazyServiceProvider.LazyGetService<IEntityHistoryHelper>(NullEntityHistoryHelper.Instance);
public IAuditingManager AuditingManager { get; set; } public IAuditingManager AuditingManager => LazyServiceProvider.LazyGetRequiredService<IAuditingManager>();
public IUnitOfWorkManager UnitOfWorkManager { get; set; } public IUnitOfWorkManager UnitOfWorkManager => LazyServiceProvider.LazyGetRequiredService<IUnitOfWorkManager>();
public IClock Clock { get; set; } public IClock Clock => LazyServiceProvider.LazyGetRequiredService<IClock>();
public ILogger<AbpDbContext<TDbContext>> Logger { get; set; } public ILogger<AbpDbContext<TDbContext>> Logger => LazyServiceProvider.LazyGetService<ILogger<AbpDbContext<TDbContext>>>(NullLogger<AbpDbContext<TDbContext>>.Instance);
private static readonly MethodInfo ConfigureBasePropertiesMethodInfo private static readonly MethodInfo ConfigureBasePropertiesMethodInfo
= typeof(AbpDbContext<TDbContext>) = typeof(AbpDbContext<TDbContext>)
@ -85,10 +86,7 @@ namespace Volo.Abp.EntityFrameworkCore
protected AbpDbContext(DbContextOptions<TDbContext> options) protected AbpDbContext(DbContextOptions<TDbContext> options)
: base(options) : base(options)
{ {
GuidGenerator = SimpleGuidGenerator.Instance;
EntityChangeEventHelper = NullEntityChangeEventHelper.Instance;
EntityHistoryHelper = NullEntityHistoryHelper.Instance;
Logger = NullLogger<AbpDbContext<TDbContext>>.Instance;
} }
protected override void OnModelCreating(ModelBuilder modelBuilder) protected override void OnModelCreating(ModelBuilder modelBuilder)
@ -564,7 +562,7 @@ namespace Volo.Abp.EntityFrameworkCore
!typeof(TEntity).IsDefined(typeof(OwnedAttribute), true) && !typeof(TEntity).IsDefined(typeof(OwnedAttribute), true) &&
!mutableEntityType.IsOwned()) !mutableEntityType.IsOwned())
{ {
if (Clock == null || !Clock.SupportsMultipleTimezone) if (LazyServiceProvider == null || Clock == null || !Clock.SupportsMultipleTimezone)
{ {
return; return;
} }

26
framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureInterceptor.cs

@ -1,4 +1,6 @@
using System.Threading.Tasks; using System;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Aspects; using Volo.Abp.Aspects;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
using Volo.Abp.DynamicProxy; using Volo.Abp.DynamicProxy;
@ -7,15 +9,14 @@ namespace Volo.Abp.Features
{ {
public class FeatureInterceptor : AbpInterceptor, ITransientDependency public class FeatureInterceptor : AbpInterceptor, ITransientDependency
{ {
private readonly IMethodInvocationFeatureCheckerService _methodInvocationFeatureCheckerService; private readonly IServiceScopeFactory _serviceScopeFactory;
public FeatureInterceptor( public FeatureInterceptor(IServiceScopeFactory serviceScopeFactory)
IMethodInvocationFeatureCheckerService methodInvocationFeatureCheckerService)
{ {
_methodInvocationFeatureCheckerService = methodInvocationFeatureCheckerService; _serviceScopeFactory = serviceScopeFactory;
} }
public async override Task InterceptAsync(IAbpMethodInvocation invocation) public override async Task InterceptAsync(IAbpMethodInvocation invocation)
{ {
if (AbpCrossCuttingConcerns.IsApplied(invocation.TargetObject, AbpCrossCuttingConcerns.FeatureChecking)) if (AbpCrossCuttingConcerns.IsApplied(invocation.TargetObject, AbpCrossCuttingConcerns.FeatureChecking))
{ {
@ -29,11 +30,14 @@ namespace Volo.Abp.Features
protected virtual async Task CheckFeaturesAsync(IAbpMethodInvocation invocation) protected virtual async Task CheckFeaturesAsync(IAbpMethodInvocation invocation)
{ {
await _methodInvocationFeatureCheckerService.CheckAsync( using (var scope = _serviceScopeFactory.CreateScope())
new MethodInvocationFeatureCheckerContext( {
invocation.Method await scope.ServiceProvider.GetRequiredService<IMethodInvocationFeatureCheckerService>().CheckAsync(
) new MethodInvocationFeatureCheckerContext(
); invocation.Method
)
);
}
} }
} }
} }

14
framework/src/Volo.Abp.MemoryDb/Volo/Abp/Domain/Repositories/MemoryDb/MemoryDbRepository.cs

@ -39,23 +39,19 @@ namespace Volo.Abp.Domain.Repositories.MemoryDb
protected IMemoryDatabaseProvider<TMemoryDbContext> DatabaseProvider { get; } protected IMemoryDatabaseProvider<TMemoryDbContext> DatabaseProvider { get; }
public ILocalEventBus LocalEventBus { get; set; } public ILocalEventBus LocalEventBus => LazyServiceProvider.LazyGetService<ILocalEventBus>(NullLocalEventBus.Instance);
public IDistributedEventBus DistributedEventBus { get; set; } public IDistributedEventBus DistributedEventBus => LazyServiceProvider.LazyGetService<IDistributedEventBus>(NullDistributedEventBus.Instance);
public IEntityChangeEventHelper EntityChangeEventHelper { get; set; } public IEntityChangeEventHelper EntityChangeEventHelper => LazyServiceProvider.LazyGetService<IEntityChangeEventHelper>(NullEntityChangeEventHelper.Instance);
public IAuditPropertySetter AuditPropertySetter { get; set; } public IGuidGenerator GuidGenerator => LazyServiceProvider.LazyGetService<IGuidGenerator>(SimpleGuidGenerator.Instance);
public IGuidGenerator GuidGenerator { get; set; } public IAuditPropertySetter AuditPropertySetter => LazyServiceProvider.LazyGetRequiredService<IAuditPropertySetter>();
public MemoryDbRepository(IMemoryDatabaseProvider<TMemoryDbContext> databaseProvider) public MemoryDbRepository(IMemoryDatabaseProvider<TMemoryDbContext> databaseProvider)
{ {
DatabaseProvider = databaseProvider; DatabaseProvider = databaseProvider;
LocalEventBus = NullLocalEventBus.Instance;
DistributedEventBus = NullDistributedEventBus.Instance;
EntityChangeEventHelper = NullEntityChangeEventHelper.Instance;
} }
[Obsolete("This method will be removed in future versions.")] [Obsolete("This method will be removed in future versions.")]

17
framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/MongoDbRepository.cs

@ -61,26 +61,21 @@ namespace Volo.Abp.Domain.Repositories.MongoDB
protected IMongoDbContextProvider<TMongoDbContext> DbContextProvider { get; } protected IMongoDbContextProvider<TMongoDbContext> DbContextProvider { get; }
public ILocalEventBus LocalEventBus { get; set; } public ILocalEventBus LocalEventBus => LazyServiceProvider.LazyGetService<ILocalEventBus>(NullLocalEventBus.Instance);
public IDistributedEventBus DistributedEventBus { get; set; } public IDistributedEventBus DistributedEventBus => LazyServiceProvider.LazyGetService<IDistributedEventBus>(NullDistributedEventBus.Instance);
public IEntityChangeEventHelper EntityChangeEventHelper { get; set; } public IEntityChangeEventHelper EntityChangeEventHelper => LazyServiceProvider.LazyGetService<IEntityChangeEventHelper>(NullEntityChangeEventHelper.Instance);
public IGuidGenerator GuidGenerator { get; set; } public IGuidGenerator GuidGenerator => LazyServiceProvider.LazyGetService<IGuidGenerator>(SimpleGuidGenerator.Instance);
public IAuditPropertySetter AuditPropertySetter { get; set; } public IAuditPropertySetter AuditPropertySetter => LazyServiceProvider.LazyGetRequiredService<IAuditPropertySetter>();
public IMongoDbBulkOperationProvider BulkOperationProvider { get; set; } public IMongoDbBulkOperationProvider BulkOperationProvider => LazyServiceProvider.LazyGetService<IMongoDbBulkOperationProvider>();
public MongoDbRepository(IMongoDbContextProvider<TMongoDbContext> dbContextProvider) public MongoDbRepository(IMongoDbContextProvider<TMongoDbContext> dbContextProvider)
{ {
DbContextProvider = dbContextProvider; DbContextProvider = dbContextProvider;
LocalEventBus = NullLocalEventBus.Instance;
DistributedEventBus = NullDistributedEventBus.Instance;
EntityChangeEventHelper = NullEntityChangeEventHelper.Instance;
GuidGenerator = SimpleGuidGenerator.Instance;
} }
public override async Task<TEntity> InsertAsync( public override async Task<TEntity> InsertAsync(

27
framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/MenuConfigurationContext.cs

@ -4,35 +4,19 @@ using JetBrains.Annotations;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Localization; using Microsoft.Extensions.Localization;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.UI.Navigation namespace Volo.Abp.UI.Navigation
{ {
public class MenuConfigurationContext : IMenuConfigurationContext public class MenuConfigurationContext : IMenuConfigurationContext
{ {
public IServiceProvider ServiceProvider { get; } public IServiceProvider ServiceProvider { get; }
private readonly object _serviceProviderLock = new object();
private TRef LazyGetRequiredService<TRef>(Type serviceType, ref TRef reference) private readonly IAbpLazyServiceProvider _lazyServiceProvider;
{
if (reference == null)
{
lock (_serviceProviderLock)
{
if (reference == null)
{
reference = (TRef)ServiceProvider.GetRequiredService(serviceType);
}
}
}
return reference;
}
public IAuthorizationService AuthorizationService => LazyGetRequiredService(typeof(IAuthorizationService), ref _authorizationService); public IAuthorizationService AuthorizationService => _lazyServiceProvider.LazyGetRequiredService<IAuthorizationService>();
private IAuthorizationService _authorizationService;
private IStringLocalizerFactory _stringLocalizerFactory; public IStringLocalizerFactory StringLocalizerFactory => _lazyServiceProvider.LazyGetRequiredService<IStringLocalizerFactory>();
public IStringLocalizerFactory StringLocalizerFactory => LazyGetRequiredService(typeof(IStringLocalizerFactory),ref _stringLocalizerFactory);
public ApplicationMenu Menu { get; } public ApplicationMenu Menu { get; }
@ -40,6 +24,7 @@ namespace Volo.Abp.UI.Navigation
{ {
Menu = menu; Menu = menu;
ServiceProvider = serviceProvider; ServiceProvider = serviceProvider;
_lazyServiceProvider = ServiceProvider.GetRequiredService<IAbpLazyServiceProvider>();
} }
public Task<bool> IsGrantedAsync(string policyName) public Task<bool> IsGrantedAsync(string policyName)
@ -58,7 +43,7 @@ namespace Volo.Abp.UI.Navigation
{ {
return StringLocalizerFactory.Create<T>(); return StringLocalizerFactory.Create<T>();
} }
[NotNull] [NotNull]
public IStringLocalizer GetLocalizer(Type resourceType) public IStringLocalizer GetLocalizer(Type resourceType)
{ {

48
framework/src/Volo.Abp.Uow/Volo/Abp/Uow/UnitOfWorkInterceptor.cs

@ -1,6 +1,7 @@
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using JetBrains.Annotations; using JetBrains.Annotations;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
using Volo.Abp.DynamicProxy; using Volo.Abp.DynamicProxy;
@ -9,18 +10,11 @@ namespace Volo.Abp.Uow
{ {
public class UnitOfWorkInterceptor : AbpInterceptor, ITransientDependency public class UnitOfWorkInterceptor : AbpInterceptor, ITransientDependency
{ {
private readonly IUnitOfWorkManager _unitOfWorkManager; private readonly IServiceScopeFactory _serviceScopeFactory;
private readonly IUnitOfWorkTransactionBehaviourProvider _transactionBehaviourProvider;
private readonly AbpUnitOfWorkDefaultOptions _defaultOptions;
public UnitOfWorkInterceptor( public UnitOfWorkInterceptor(IServiceScopeFactory serviceScopeFactory)
IUnitOfWorkManager unitOfWorkManager,
IOptions<AbpUnitOfWorkDefaultOptions> options,
IUnitOfWorkTransactionBehaviourProvider transactionBehaviourProvider)
{ {
_unitOfWorkManager = unitOfWorkManager; _serviceScopeFactory = serviceScopeFactory;
_transactionBehaviourProvider = transactionBehaviourProvider;
_defaultOptions = options.Value;
} }
public override async Task InterceptAsync(IAbpMethodInvocation invocation) public override async Task InterceptAsync(IAbpMethodInvocation invocation)
@ -31,23 +25,28 @@ namespace Volo.Abp.Uow
return; return;
} }
var options = CreateOptions(invocation, unitOfWorkAttribute); using (var scope = _serviceScopeFactory.CreateScope())
//Trying to begin a reserved UOW by AbpUnitOfWorkMiddleware
if (_unitOfWorkManager.TryBeginReserved(UnitOfWork.UnitOfWorkReservationName, options))
{ {
await invocation.ProceedAsync(); var options = CreateOptions(scope.ServiceProvider, invocation, unitOfWorkAttribute);
return;
}
using (var uow = _unitOfWorkManager.Begin(options)) var unitOfWorkManager = scope.ServiceProvider.GetRequiredService<IUnitOfWorkManager>();
{
await invocation.ProceedAsync(); //Trying to begin a reserved UOW by AbpUnitOfWorkMiddleware
await uow.CompleteAsync(); if (unitOfWorkManager.TryBeginReserved(UnitOfWork.UnitOfWorkReservationName, options))
{
await invocation.ProceedAsync();
return;
}
using (var uow = unitOfWorkManager.Begin(options))
{
await invocation.ProceedAsync();
await uow.CompleteAsync();
}
} }
} }
private AbpUnitOfWorkOptions CreateOptions(IAbpMethodInvocation invocation, [CanBeNull] UnitOfWorkAttribute unitOfWorkAttribute) private AbpUnitOfWorkOptions CreateOptions(IServiceProvider serviceProvider, IAbpMethodInvocation invocation, [CanBeNull] UnitOfWorkAttribute unitOfWorkAttribute)
{ {
var options = new AbpUnitOfWorkOptions(); var options = new AbpUnitOfWorkOptions();
@ -55,8 +54,9 @@ namespace Volo.Abp.Uow
if (unitOfWorkAttribute?.IsTransactional == null) if (unitOfWorkAttribute?.IsTransactional == null)
{ {
options.IsTransactional = _defaultOptions.CalculateIsTransactional( var defaultOptions = serviceProvider.GetRequiredService<IOptions<AbpUnitOfWorkDefaultOptions>>().Value;
autoValue: _transactionBehaviourProvider.IsTransactional options.IsTransactional = defaultOptions.CalculateIsTransactional(
autoValue: serviceProvider.GetRequiredService<IUnitOfWorkTransactionBehaviourProvider>().IsTransactional
?? !invocation.Method.Name.StartsWith("Get", StringComparison.InvariantCultureIgnoreCase) ?? !invocation.Method.Name.StartsWith("Get", StringComparison.InvariantCultureIgnoreCase)
); );
} }

2
framework/src/Volo.Abp.Validation/Volo/Abp/Validation/ValidationInterceptor.cs

@ -13,7 +13,7 @@ namespace Volo.Abp.Validation
_methodInvocationValidator = methodInvocationValidator; _methodInvocationValidator = methodInvocationValidator;
} }
public async override Task InterceptAsync(IAbpMethodInvocation invocation) public override async Task InterceptAsync(IAbpMethodInvocation invocation)
{ {
Validate(invocation); Validate(invocation);
await invocation.ProceedAsync(); await invocation.ProceedAsync();

Loading…
Cancel
Save