Browse Source

Merge branch 'dev' into timezone

pull/16861/head
maliming 3 years ago
parent
commit
5823d1f30b
No known key found for this signature in database GPG Key ID: A646B9CB645ECEA4
  1. 3
      abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json
  2. 12
      abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/en.json
  3. 45
      docs/en/API/Auto-API-Controllers.md
  4. 25
      docs/en/API/Swagger-Integration.md
  5. 6
      docs/en/Background-Jobs-Hangfire.md
  6. 2
      docs/en/Contribution/How-to-Contribute-abp.io-as-a-frontend-developer.md
  7. 45
      docs/en/Distributed-Event-Bus.md
  8. 81
      docs/en/Image-Manipulation.md
  9. 27
      docs/en/Local-Event-Bus.md
  10. 2
      docs/zh-Hans/Deployment/Index.md
  11. 7
      framework/Volo.Abp.sln
  12. 4
      framework/src/Volo.Abp.AspNetCore.Authentication.OpenIdConnect/Volo.Abp.AspNetCore.Authentication.OpenIdConnect.csproj
  13. 78
      framework/src/Volo.Abp.AspNetCore.Components.Server/Microsoft/AspNetCore/Authentication/Cookies/CookieAuthenticationOptionsExtensions.cs
  14. 1
      framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo.Abp.AspNetCore.Components.WebAssembly.csproj
  15. 2
      framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/AbpAspNetCoreComponentsWebAssemblyModule.cs
  16. 40
      framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/ClientProxyExceptionEventHandler.cs
  17. 1
      framework/src/Volo.Abp.AspNetCore.Components/Volo.Abp.AspNetCore.Components.csproj
  18. 4
      framework/src/Volo.Abp.AspNetCore.Components/Volo/Abp/AspNetCore/Components/AbpAspNetCoreComponentsModule.cs
  19. 3
      framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcOptions.cs
  20. 38
      framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Conventions/AbpServiceConvention.cs
  21. 100
      framework/src/Volo.Abp.AspNetCore/Microsoft/Extensions/DependencyInjection/CookieAuthenticationOptionsExtensions.cs
  22. 2
      framework/src/Volo.Abp.AspNetCore/Volo.Abp.AspNetCore.csproj
  23. 14
      framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Controllers/ReplaceControllersAttribute.cs
  24. 2
      framework/src/Volo.Abp.Authorization.Abstractions/Volo.Abp.Authorization.Abstractions.csproj
  25. 2
      framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/AbpAuthorizationAbstractionsModule.cs
  26. 4
      framework/src/Volo.Abp.Authorization/Volo.Abp.Authorization.csproj
  27. 4
      framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AbpAuthorizationModule.cs
  28. 1
      framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo.Abp.BackgroundJobs.Abstractions.csproj
  29. 4
      framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/AbpBackgroundJobsAbstractionsModule.cs
  30. 1
      framework/src/Volo.Abp.BackgroundJobs/Volo.Abp.BackgroundJobs.csproj
  31. 4
      framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/AbpBackgroundJobsModule.cs
  32. 8
      framework/src/Volo.Abp.BlazoriseUI/Volo.Abp.BlazoriseUI.csproj
  33. 2
      framework/src/Volo.Abp.Caching.StackExchangeRedis/Volo.Abp.Caching.StackExchangeRedis.csproj
  34. 2
      framework/src/Volo.Abp.Caching.StackExchangeRedis/Volo/Abp/Caching/StackExchangeRedis/AbpCachingStackExchangeRedisModule.cs
  35. 60
      framework/src/Volo.Abp.Caching.StackExchangeRedis/Volo/Abp/Caching/StackExchangeRedis/AbpRedisCache.cs
  36. 1
      framework/src/Volo.Abp.Caching/Volo.Abp.Caching.csproj
  37. 10
      framework/src/Volo.Abp.Caching/Volo/Abp/Caching/AbpDistributedCacheOptions.cs
  38. 2
      framework/src/Volo.Abp.Caching/Volo/Abp/Caching/CacheNameAttribute.cs
  39. 131
      framework/src/Volo.Abp.Caching/Volo/Abp/Caching/DistributedCache.cs
  40. 4
      framework/src/Volo.Abp.Caching/Volo/Abp/Caching/ICacheSupportsMultipleItems.cs
  41. 32
      framework/src/Volo.Abp.Caching/Volo/Abp/Caching/IDistributedCache.cs
  42. 2
      framework/src/Volo.Abp.Caching/Volo/Abp/Caching/UnitOfWorkCacheItem.cs
  43. 2
      framework/src/Volo.Abp.Caching/Volo/Abp/Caching/UnitOfWorkCacheItemExtensions.cs
  44. 12
      framework/src/Volo.Abp.Core/Microsoft/Extensions/Configuration/AbpConfigurationBuilderOptions.cs
  45. 6
      framework/src/Volo.Abp.Core/Microsoft/Extensions/Configuration/ConfigurationHelper.cs
  46. 11
      framework/src/Volo.Abp.Core/Microsoft/Extensions/DependencyInjection/ServiceCollectionApplicationExtensions.cs
  47. 26
      framework/src/Volo.Abp.Core/Microsoft/Extensions/DependencyInjection/ServiceCollectionCommonExtensions.cs
  48. 2
      framework/src/Volo.Abp.Core/Microsoft/Extensions/DependencyInjection/ServiceCollectionConfigurationExtensions.cs
  49. 2
      framework/src/Volo.Abp.Core/Microsoft/Extensions/DependencyInjection/ServiceCollectionObjectAccessorExtensions.cs
  50. 17
      framework/src/Volo.Abp.Core/Microsoft/Extensions/Logging/AbpLoggerExtensions.cs
  51. 2
      framework/src/Volo.Abp.Core/System/AbpObjectExtensions.cs
  52. 12
      framework/src/Volo.Abp.Core/System/AbpStringExtensions.cs
  53. 4
      framework/src/Volo.Abp.Core/System/AbpTypeExtensions.cs
  54. 2
      framework/src/Volo.Abp.Core/System/Collections/Generic/AbpCollectionExtensions.cs
  55. 20
      framework/src/Volo.Abp.Core/System/Collections/Generic/AbpDictionaryExtensions.cs
  56. 4
      framework/src/Volo.Abp.Core/System/Collections/Generic/AbpListExtensions.cs
  57. 24
      framework/src/Volo.Abp.Core/System/Linq/PredicateOperator.cs
  58. 2
      framework/src/Volo.Abp.Core/System/Reflection/AbpAssemblyExtensions.cs
  59. 6
      framework/src/Volo.Abp.Core/System/Reflection/AbpMemberInfoExtensions.cs
  60. 2
      framework/src/Volo.Abp.Core/Volo.Abp.Core.csproj
  61. 16
      framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationBase.cs
  62. 6
      framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationCreationOptions.cs
  63. 16
      framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationFactory.cs
  64. 3
      framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationWithExternalServiceProvider.cs
  65. 9
      framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationWithInternalServiceProvider.cs
  66. 2
      framework/src/Volo.Abp.Core/Volo/Abp/AbpHostEnvironment.cs
  67. 2
      framework/src/Volo.Abp.Core/Volo/Abp/Bundling/BundleContext.cs
  68. 2
      framework/src/Volo.Abp.Core/Volo/Abp/Bundling/BundleDefinition.cs
  69. 12
      framework/src/Volo.Abp.Core/Volo/Abp/BusinessException.cs
  70. 6
      framework/src/Volo.Abp.Core/Volo/Abp/Check.cs
  71. 2
      framework/src/Volo.Abp.Core/Volo/Abp/Content/IRemoteStreamContent.cs
  72. 4
      framework/src/Volo.Abp.Core/Volo/Abp/Content/RemoteStreamContent.cs
  73. 6
      framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/AbpLazyServiceProvider.cs
  74. 16
      framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/CachedServiceProviderBase.cs
  75. 8
      framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/ConventionalRegistrarBase.cs
  76. 4
      framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/IAbpLazyServiceProvider.cs
  77. 3
      framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/IObjectAccessor.cs
  78. 4
      framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/ObjectAccessor.cs
  79. 4
      framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/RootServiceProvider.cs
  80. 8
      framework/src/Volo.Abp.Core/Volo/Abp/DisposeAction.cs
  81. 13
      framework/src/Volo.Abp.Core/Volo/Abp/DynamicProxy/ProxyHelper.cs
  82. 2
      framework/src/Volo.Abp.Core/Volo/Abp/ExceptionHandling/IHasErrorCode.cs
  83. 2
      framework/src/Volo.Abp.Core/Volo/Abp/ExceptionHandling/IHasErrorDetails.cs
  84. 2
      framework/src/Volo.Abp.Core/Volo/Abp/IAbpHostEnvironment.cs
  85. 3
      framework/src/Volo.Abp.Core/Volo/Abp/IApplicationInfoAccessor.cs
  86. 9
      framework/src/Volo.Abp.Core/Volo/Abp/IO/FileHelper.cs
  87. 4
      framework/src/Volo.Abp.Core/Volo/Abp/Localization/CultureHelper.cs
  88. 6
      framework/src/Volo.Abp.Core/Volo/Abp/Logging/AbpInitLogEntry.cs
  89. 6
      framework/src/Volo.Abp.Core/Volo/Abp/Logging/DefaultInitLogger.cs
  90. 2
      framework/src/Volo.Abp.Core/Volo/Abp/Modularity/AbpModule.cs
  91. 2
      framework/src/Volo.Abp.Core/Volo/Abp/Modularity/DependsOnAttribute.cs
  92. 2
      framework/src/Volo.Abp.Core/Volo/Abp/Modularity/ModuleLoader.cs
  93. 2
      framework/src/Volo.Abp.Core/Volo/Abp/Modularity/PlugIns/FilePlugInSource.cs
  94. 2
      framework/src/Volo.Abp.Core/Volo/Abp/Modularity/PlugIns/FolderPlugInSource.cs
  95. 2
      framework/src/Volo.Abp.Core/Volo/Abp/Modularity/PlugIns/TypePlugInSource.cs
  96. 6
      framework/src/Volo.Abp.Core/Volo/Abp/Modularity/ServiceConfigurationContext.cs
  97. 4
      framework/src/Volo.Abp.Core/Volo/Abp/NameValue.cs
  98. 10
      framework/src/Volo.Abp.Core/Volo/Abp/ObjectHelper.cs
  99. 4
      framework/src/Volo.Abp.Core/Volo/Abp/Options/AbpOptionsFactory.cs
  100. 2
      framework/src/Volo.Abp.Core/Volo/Abp/Reflection/AssemblyHelper.cs

3
abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json

@ -460,6 +460,7 @@
"ReloadFromSourceConfirmationMessage": "This post will be refreshed from \"{0}\". Do you want to continue?", "ReloadFromSourceConfirmationMessage": "This post will be refreshed from \"{0}\". Do you want to continue?",
"UnitPrice": "Unit Price", "UnitPrice": "Unit Price",
"OverallDiscountAmount": "Overall Discount Amount", "OverallDiscountAmount": "Overall Discount Amount",
"DiscountAmount": "Discount Amount" "DiscountAmount": "Discount Amount",
"FullChangeHistory": "Full Change History"
} }
} }

12
abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/en.json

@ -420,14 +420,16 @@
"CreateSolutionFolder": "Create Solution Folder", "CreateSolutionFolder": "Create Solution Folder",
"CreateSolutionFolderOption": "Specifies if the project will be in a new folder in the output folder or directly the output folder.", "CreateSolutionFolderOption": "Specifies if the project will be in a new folder in the output folder or directly the output folder.",
"BooksPageTitle": "ABP Books", "BooksPageTitle": "ABP Books",
"PackageDetailPage_NuGetPackageInstallationOptions": "There are two ways to install <code>{0}</code> NuGet package to your project", "PackageDetailPage_NuGetPackageInstallationOptions": "There are three ways to install <code>{0}</code> NuGet package to your project",
"PackageDetailPage_InstallingWithABPCLI": "1: Installing with the ABP CLI", "PackageDetailPage_InstallingWithABPCLI": "1: Installing with the ABP CLI",
"PackageDetailPage_InstallingWithABPCLIDescription1": "If you haven't installed the <a href=\"https://docs.abp.io/en/abp/latest/CLI\">ABP CLI</a>, first install by executing the following command in a command-line terminal", "PackageDetailPage_InstallingWithABPCLIDescription1": "If you haven't installed the <a href=\"https://docs.abp.io/en/abp/latest/CLI\">ABP CLI</a>, first install by executing the following command in a command-line terminal",
"PackageDetailPage_InstallingWithABPCLIDescription2": "Once you have installed the ABP CLI, open a command-line terminal in the location of the project (<code>.csproj</code> file) you want to install it and execute the following command", "PackageDetailPage_InstallingWithABPCLIDescription2": "Once you have installed the ABP CLI, open a command-line terminal in the location of the project (<code>.csproj</code> file) you want to install it and execute the following command",
"PackageDetailPage_InstallingWithABPCLIDescription3": "It will add the <code>{0}</code> package reference to your project and the <code>{1}</code> dependency to your module class.", "PackageDetailPage_InstallingWithABPCLIDescription3": "It will add the <code>{0}</code> package reference to your project and the <code>{1}</code> dependency to your module class.",
"PackageDetailPage_ManualInstallation": "2: Manual Installation", "PackageDetailPage_ManualInstallation": "2: Installing with the Dotnet CLI",
"PackageDetailPage_ManualInstallationDesription1": "Add <code>{0}</code> NuGet package reference to your project using your IDE or executing the following command", "PackageDetailPage_ManualInstallationDescription1": "Add <code>{0}</code> NuGet package reference to your project using your IDE or executing the following command",
"PackageDetailPage_ManualInstallationDesription2": "Then add the <code>{0}</code> dependency to your <a href=\"https://docs.abp.io/en/abp/latest/Module-Development-Basics\">module class</a> as shown in the following example", "PackageDetailPage_ManualInstallationDescription2": "Then add the <code>{0}</code> dependency to your <a href=\"https://docs.abp.io/en/abp/latest/Module-Development-Basics\">module class</a> as shown in the following example",
"PackageDetailPage_SeeDocumentation": "<a href=\"{0}\">See the documentation</a> to learn how to use this package in your applications." "PackageDetailPage_SeeDocumentation": "<a href=\"{0}\">See the documentation</a> to learn how to use this package in your applications.",
"PackageDetailPage_InstallingUsingPMC": "3: Installing with the Package Manager Console",
"PackageDetailPage_InstallingUsingPMCDescription1": "Open the <strong>Package Manager Console</strong> in Visual Studio (Tools -> Nuget Package Manager -> Package Manager Console) and execute the following command"
} }
} }

45
docs/en/API/Auto-API-Controllers.md

@ -169,3 +169,48 @@ public class PersonAppService : ApplicationService
```` ````
Disabled `IsMetadataEnabled` which hides this service from API explorer and it will not be discoverable. However, it still can be usable for the clients know the exact API path/route. Disabled `IsMetadataEnabled` which hides this service from API explorer and it will not be discoverable. However, it still can be usable for the clients know the exact API path/route.
## Replace or Remove Controllers.
In addition to [Overriding a Controller](../Customizing-Application-Modules-Overriding-Services.md#example-overriding-a-controller), you can also use a completely independent **Controller** to replace the controller in the framework or module.
They have the same [route](https://learn.microsoft.com/en-us/aspnet/core/mvc/controllers/routing?view=aspnetcore-7.0), but can have **different** input and output parameters.
### Replace built-in AbpApplicationConfigurationController
The `ReplaceControllersAttribute` indicates the replaced controller type.
````csharp
[ReplaceControllers(typeof(AbpApplicationConfigurationController))]
[Area("abp")]
[RemoteService(Name = "abp")]
public class ReplaceBuiltInController : AbpController
{
[HttpGet("api/abp/application-configuration")]
public virtual Task<MyApplicationConfigurationDto> GetAsync(MyApplicationConfigurationRequestOptions options)
{
return Task.FromResult(new MyApplicationConfigurationDto());
}
}
public class MyApplicationConfigurationRequestOptions : ApplicationConfigurationRequestOptions
{
}
public class MyApplicationConfigurationDto : ApplicationConfigurationDto
{
}
````
### Remove contoller
Configure `ControllersToRemove` of `AbpAspNetCoreMvcOptions` to remove the controllers.
````csharp
services.Configure<AbpAspNetCoreMvcOptions>(options =>
{
options.ControllersToRemove.Add(typeof(AbpLanguagesController));
});
````

25
docs/en/API/Swagger-Integration.md

@ -43,7 +43,7 @@ If you want to manually install;
## Configuration ## Configuration
First, we need to use `AddAbpSwaggerGen` extension to configure Swagger in `ConfigureServices` method of our module. First, we need to use `AddAbpSwaggerGen` extension to configure Swagger in `ConfigureServices` method of our module:
```csharp ```csharp
public override void ConfigureServices(ServiceConfigurationContext context) public override void ConfigureServices(ServiceConfigurationContext context)
@ -63,21 +63,21 @@ public override void ConfigureServices(ServiceConfigurationContext context)
} }
``` ```
Then we can use Swagger UI by calling `UseAbpSwaggerUI` method in the `OnApplicationInitialization` method of our module. Then we can use Swagger UI by calling `UseAbpSwaggerUI` method in the `OnApplicationInitialization` method of our module:
```csharp ```csharp
public override void OnApplicationInitialization(ApplicationInitializationContext context) public override void OnApplicationInitialization(ApplicationInitializationContext context)
{ {
var app = context.GetApplicationBuilder(); var app = context.GetApplicationBuilder();
//... other configarations. //... other configurations.
app.UseAbpSwaggerUI(options => app.UseAbpSwaggerUI(options =>
{ {
options.SwaggerEndpoint("/swagger/v1/swagger.json", "Test API"); options.SwaggerEndpoint("/swagger/v1/swagger.json", "Test API");
}); });
//... other configarations. //... other configurations.
} }
``` ```
@ -103,9 +103,7 @@ For non MVC/Tiered applications, we need to configure Swagger with OAUTH to hand
> ABP Framework uses OpenIddict by default. To get more information about OpenIddict, check this [documentation](../Modules/OpenIddict.md). > ABP Framework uses OpenIddict by default. To get more information about OpenIddict, check this [documentation](../Modules/OpenIddict.md).
To do that, we need to use `AddAbpSwaggerGenWithOAuth` extension to configure Swagger with OAuth issuer and scopes in `ConfigureServices` method of our module:
To do that, we need to use `AddAbpSwaggerGenWithOAuth` extension to configure Swagger with OAuth issuer and scopes in `ConfigureServices` method of our module.
```csharp ```csharp
public override void ConfigureServices(ServiceConfigurationContext context) public override void ConfigureServices(ServiceConfigurationContext context)
@ -130,17 +128,14 @@ public override void ConfigureServices(ServiceConfigurationContext context)
} }
``` ```
Then we can use Swagger UI by calling `UseAbpSwaggerUI` method in the `OnApplicationInitialization` method of our module. Then we can use Swagger UI by calling `UseAbpSwaggerUI` method in the `OnApplicationInitialization` method of our module:
> Do not forget to set `OAuthClientId` and `OAuthClientSecret`.
```csharp ```csharp
public override void OnApplicationInitialization(ApplicationInitializationContext context) public override void OnApplicationInitialization(ApplicationInitializationContext context)
{ {
var app = context.GetApplicationBuilder(); var app = context.GetApplicationBuilder();
//... other configarations. //... other configurations.
app.UseAbpSwaggerUI(options => app.UseAbpSwaggerUI(options =>
{ {
@ -151,6 +146,8 @@ public override void OnApplicationInitialization(ApplicationInitializationContex
options.OAuthClientSecret("1q2w3e*"); // clientSecret options.OAuthClientSecret("1q2w3e*"); // clientSecret
}); });
//... other configarations. //... other configurations.
} }
``` ```
> Do not forget to set `OAuthClientId` and `OAuthClientSecret`.

6
docs/en/Background-Jobs-Hangfire.md

@ -52,7 +52,7 @@ After you have installed these NuGet packages, you need to configure your projec
var configuration = context.Services.GetConfiguration(); var configuration = context.Services.GetConfiguration();
var hostingEnvironment = context.Services.GetHostingEnvironment(); var hostingEnvironment = context.Services.GetHostingEnvironment();
//... other configarations. //... other configurations.
ConfigureHangfire(context, configuration); ConfigureHangfire(context, configuration);
} }
@ -68,7 +68,7 @@ After you have installed these NuGet packages, you need to configure your projec
> You have to configure a storage for Hangfire. > You have to configure a storage for Hangfire.
2. If you want to use hangfire's dashboard, you can add `UseHangfireDashboard` call in the `OnApplicationInitialization` method in `Module` class 2. If you want to use hangfire's dashboard, you can add `UseHangfireDashboard` call in the `OnApplicationInitialization` method in `Module` class:
````csharp ````csharp
public override void OnApplicationInitialization(ApplicationInitializationContext context) public override void OnApplicationInitialization(ApplicationInitializationContext context)
@ -84,7 +84,7 @@ After you have installed these NuGet packages, you need to configure your projec
### Specifying Queue ### Specifying Queue
You can use the [`QueueAttribute`](https://docs.hangfire.io/en/latest/background-processing/configuring-queues.html) to specify the queue. You can use the [`QueueAttribute`](https://docs.hangfire.io/en/latest/background-processing/configuring-queues.html) to specify the queue:
````csharp ````csharp
using System.Threading.Tasks; using System.Threading.Tasks;

2
docs/en/Contribution/How-to-Contribute-abp.io-as-a-frontend-developer.md

@ -55,4 +55,4 @@ Your backend should be running successfully
There is a demo app. The path of the demo app is `npm\ng-packs\apps\dev-app`. The demo app is connected to the packages with local references. Open the terminal in `npm\ng-packs\apps\dev-app` and execute `yarn` or `npm i` in terminal. After the package installed run `npm start` or `yarn start`. There is a demo app. The path of the demo app is `npm\ng-packs\apps\dev-app`. The demo app is connected to the packages with local references. Open the terminal in `npm\ng-packs\apps\dev-app` and execute `yarn` or `npm i` in terminal. After the package installed run `npm start` or `yarn start`.
The repo uses Nx and packages connected with `local references`. The packages path is `”npm\ng-packs\packages` The repo uses Nx and packages connected with `local references`. The packages path is `npm\ng-packs\packages`

45
docs/en/Distributed-Event-Bus.md

@ -185,6 +185,51 @@ If you perform **database operations** and use the [repositories](Repositories.m
> The handler class must be registered to the dependency injection (DI). The sample above uses the `ITransientDependency` to accomplish it. See the [DI document](Dependency-Injection.md) for more options. > The handler class must be registered to the dependency injection (DI). The sample above uses the `ITransientDependency` to accomplish it. See the [DI document](Dependency-Injection.md) for more options.
## Monitoring Distributed Events
The ABP Framework allows you to stay informed when your application **receives** or **sends** a distributed event. This capability enables you to track the event flow within your application and take appropriate actions based on the received or sent distributed events.
### Received Events
The `DistributedEventReceived` local event is published when your application receives an event from the distributed event bus. `DistributedEventReceived` class has the following fields:
- **`Source`:** It represents the source of the distributed event. Source can be `Direct`, `Inbox`, `Outbox`.
- **`EventName`:** It represents the [name](#event-name) of the event received.
- **`EventData`:** It represents the actual data associated with the event received. Since it is of type `object`, it can hold any type of data.
**Example: Get informed when your application receives an event from the distributed event bus**
```csharp
public class DistributedEventReceivedHandler : ILocalEventHandler<DistributedEventReceived>, ITransientDependency
{
public async Task HandleEventAsync(DistributedEventReceived eventData)
{
// TODO: IMPLEMENT YOUR LOGIC...
}
}
```
### Sent Events
The `DistributedEventSent` local event is published when your application sends an event to the distributed event bus. `DistributedEventSent` class has the following fields:
- **`Source`:** It represents the source of the distributed event. Source can be `Direct`, `Inbox`, `Outbox`.
- **`EventName`:** It represents the [name](#event-name) of the event sent.
- **`EventData`:** It represents the actual data associated with the event sent. Since it is of type `object`, it can hold any type of data.
**Example: Get informed when your application sends an event to the distributed event bus**
```csharp
public class DistributedEventSentHandler : ILocalEventHandler<DistributedEventSent>, ITransientDependency
{
public async Task HandleEventAsync(DistributedEventSent eventData)
{
// TODO: IMPLEMENT YOUR LOGIC...
}
}
```
You can seamlessly integrate event-tracking capabilities into your application by subscribing to the `DistributedEventReceived` and `DistributedEventSent` local events as above examples. This empowers you to effectively monitor the messaging flow, diagnose any potential issues, and gain valuable insights into the behavior of your distributed messaging system.
## Pre-Defined Events ## Pre-Defined Events

81
docs/en/Image-Manipulation.md

@ -5,7 +5,7 @@ ABP Framework provides services to compress and resize images and implements the
## Installation ## Installation
It is suggested to use the [ABP CLI](CLI.md) to install this package. You can add this package to your application by either using the [ABP CLI](CLI.md) or manually installing it. Using the [ABP CLI](CLI.md) is the recommended approach.
### Using the ABP CLI ### Using the ABP CLI
@ -116,6 +116,8 @@ public enum ImageResizeMode : byte
} }
``` ```
> See the [ImageSharp documentation](https://docs.sixlabors.com/api/ImageSharp/SixLabors.ImageSharp.Processing.ResizeMode.html) for more information about the resize modes.
### ImageResizeResult ### ImageResizeResult
The `ImageResizeResult` is a generic class that is used to return the result of the image resize operations. It has the following properties: The `ImageResizeResult` is a generic class that is used to return the result of the image resize operations. It has the following properties:
@ -196,7 +198,31 @@ public enum ImageProcessState : byte
## Magick.NET Provider ## Magick.NET Provider
`Volo.Abp.Imaging.MagickNet` NuGet package implements the image operations using the [Magick.NET](https://github.com/dlemstra/Magick.NET) library. If you want to use that library as image process provider, add the `Volo.Abp.Imaging.MagickNet` NuGet package to your project, then add `AbpImagingMagickNetModule` to your [module](Module-Development-Basics.md)'s dependency list: `Volo.Abp.Imaging.MagickNet` NuGet package implements the image operations using the [Magick.NET](https://github.com/dlemstra/Magick.NET) library.
## Installation
You can add this package to your application by either using the [ABP CLI](CLI.md) or manually installing it. Using the [ABP CLI](CLI.md) is the recommended approach.
### Using the ABP CLI
Open a command line terminal in the folder of your project (.csproj file) and type the following command:
```bash
abp add-package Volo.Abp.Imaging.MagickNet
```
### Manual Installation
If you want to manually install;
1. Add the [Volo.Abp.Imaging.MagickNet](https://www.nuget.org/packages/Volo.Abp.Imaging.MagickNet) NuGet package to your project:
```
Install-Package Volo.Abp.Imaging.MagickNet
```
2. Add `AbpImagingMagickNetModule` to your [module](Module-Development-Basics.md)'s dependency list:
```csharp ```csharp
[DependsOn(typeof(AbpImagingMagickNetModule))] [DependsOn(typeof(AbpImagingMagickNetModule))]
@ -216,7 +242,32 @@ public class MyModule : AbpModule
## ImageSharp Provider ## ImageSharp Provider
`Volo.Abp.Imaging.ImageSharp` NuGet package implements the image operations using the [ImageSharp](https://github.com/SixLabors/ImageSharp) library. If you want to use that library as image process provider, add the `Volo.Abp.Imaging.ImageSharp` NuGet package to your project, then add `AbpImagingImageSharpModule` to your [module](Module-Development-Basics.md)'s dependency list: `Volo.Abp.Imaging.ImageSharp` NuGet package implements the image operations using the [ImageSharp](https://github.com/SixLabors/ImageSharp) library.
## Installation
You can add this package to your application by either using the [ABP CLI](CLI.md) or manually installing it. Using the [ABP CLI](CLI.md) is the recommended approach.
### Using the ABP CLI
Open a command line terminal in the folder of your project (.csproj file) and type the following command:
```bash
abp add-package Volo.Abp.Imaging.ImageSharp
```
### Manual Installation
If you want to manually install;
1. Add the [Volo.Abp.Imaging.ImageSharp](https://www.nuget.org/packages/Volo.Abp.Imaging.ImageSharp) NuGet package to your project:
```
Install-Package Volo.Abp.Imaging.ImageSharp
```
2. Add `AbpImagingImageSharpModule` to your [module](Module-Development-Basics.md)'s dependency list:
```csharp ```csharp
[DependsOn(typeof(AbpImagingImageSharpModule))] [DependsOn(typeof(AbpImagingImageSharpModule))]
@ -259,7 +310,29 @@ Configure<ImageSharpCompressOptions>(options =>
`Volo.Abp.Imaging.AspNetCore` NuGet package defines attributes for controller actions that can automatically compress and/or resize uploaded files. `Volo.Abp.Imaging.AspNetCore` NuGet package defines attributes for controller actions that can automatically compress and/or resize uploaded files.
To use the ASP.NET Core integration, add the `Volo.Abp.Imaging.AspNetCore` NuGet package to your project and add the `AbpImagingAspNetCoreModule` module to your module's dependency list: ## Installation
You can add this package to your application by either using the [ABP CLI](CLI.md) or manually installing it. Using the [ABP CLI](CLI.md) is the recommended approach.
### Using the ABP CLI
Open a command line terminal in the folder of your project (.csproj file) and type the following command:
```bash
abp add-package Volo.Abp.Imaging.AspNetCore
```
### Manual Installation
If you want to manually install;
1. Add the [Volo.Abp.Imaging.AspNetCore](https://www.nuget.org/packages/Volo.Abp.Imaging.AspNetCore) NuGet package to your project:
```
Install-Package Volo.Abp.Imaging.AspNetCore
```
2. Add `AbpImagingAspNetCoreModule` to your [module](Module-Development-Basics.md)'s dependency list:
```csharp ```csharp
[DependsOn(typeof(AbpImagingAspNetCoreModule))] [DependsOn(typeof(AbpImagingAspNetCoreModule))]

27
docs/en/Local-Event-Bus.md

@ -149,7 +149,7 @@ namespace AbpDemo
} }
```` ````
That's all. `MyHandler` is **automatically discovered** by the ABP Framework and `HandleEventAsync` is called whenever a `StockCountChangedEvent` occurs. You can inject any service and perform any required logic in your handler class. That's all. `MyHandler` is **automatically discovered** by the ABP Framework and `HandleEventAsync` is called whenever a `StockCountChangedEvent` occurs. You can inject any service and perform any required logic in your handler class.
* **One or more handlers** can subscribe to the same event. * **One or more handlers** can subscribe to the same event.
* A single event handler class can **subscribe to multiple events** by implementing the `ILocalEventHandler<TEvent>` interface for each event type. * A single event handler class can **subscribe to multiple events** by implementing the `ILocalEventHandler<TEvent>` interface for each event type.
@ -158,6 +158,29 @@ If you perform **database operations** and use the [repositories](Repositories.m
> The handler class must be registered to the dependency injection (DI). The sample above uses the `ITransientDependency` to accomplish it. See the [DI document](Dependency-Injection.md) for more options. > The handler class must be registered to the dependency injection (DI). The sample above uses the `ITransientDependency` to accomplish it. See the [DI document](Dependency-Injection.md) for more options.
### LocalEventHandlerOrder Attribute
`LocalEventHandlerOrder` attribute can be used to set the execution order for the event handlers, which can be helpful if you want to handle your event handlers in a specific order.
````csharp
[LocalEventHandlerOrder(-1)]
public class MyHandler
: ILocalEventHandler<StockCountChangedEvent>,
ITransientDependency
{
public async Task HandleEventAsync(StockCountChangedEvent eventData)
{
//TODO: your code that does something on the event
}
}
````
> By default, all event handlers have an order value of 0. Thus, if you want to take certain event handlers to be executed before other event handlers, you can set the order value as a negative value.
#### LocalEventHandlerOrderAttribute Properties
* `Order` (`int`): Used to set the execution order for a certain event handler.
### Transaction & Exception Behavior ### Transaction & Exception Behavior
Event handlers are always executed in the same [unit of work](Unit-Of-Work.md) scope, that means in the same database transaction with the code that published the event. If an event handler throws an exception, the unit of work (database transaction) is rolled back. So, **use try-catch yourself** in the event handler if you want to hide the error. Event handlers are always executed in the same [unit of work](Unit-Of-Work.md) scope, that means in the same database transaction with the code that published the event. If an event handler throws an exception, the unit of work (database transaction) is rolled back. So, **use try-catch yourself** in the event handler if you want to hide the error.
@ -205,7 +228,7 @@ The pre-built event types are;
* `EntityDeletedEventData<T>` is published just after an entity was successfully deleted. * `EntityDeletedEventData<T>` is published just after an entity was successfully deleted.
* `EntityChangedEventData<T>` is published just after an entity was successfully created, updated or deleted. It can be a shortcut if you need to listen any type of change - instead of subscribing to the individual events. * `EntityChangedEventData<T>` is published just after an entity was successfully created, updated or deleted. It can be a shortcut if you need to listen any type of change - instead of subscribing to the individual events.
#### How It Was Implemented? ### How It Was Implemented?
Pre-build events are published when you save changes to the database; Pre-build events are published when you save changes to the database;

2
docs/zh-Hans/Deployment/Index.md

@ -6,4 +6,4 @@
## 指南 ## 指南
* [部署到群集环境](Clustered-Environment.md): 讲解了当你希望同时运行应用程序的多个实例时, 如何来配置应用程序. * [部署到集群环境](Clustered-Environment.md): 讲解了当你希望同时运行应用程序的多个实例时, 如何来配置应用程序.

7
framework/Volo.Abp.sln

@ -439,6 +439,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Ldap.Abstractions"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Ddd.Domain.Shared", "src\Volo.Abp.Ddd.Domain.Shared\Volo.Abp.Ddd.Domain.Shared.csproj", "{0858571B-CE73-4AD6-BD06-EC9F0714D8E9}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Ddd.Domain.Shared", "src\Volo.Abp.Ddd.Domain.Shared\Volo.Abp.Ddd.Domain.Shared.csproj", "{0858571B-CE73-4AD6-BD06-EC9F0714D8E9}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.MultiTenancy.Abstractions", "src\Volo.Abp.MultiTenancy.Abstractions\Volo.Abp.MultiTenancy.Abstractions.csproj", "{86F3684C-A0A5-4943-8CFA-AE79E8E3E315}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Imaging.Abstractions", "src\Volo.Abp.Imaging.Abstractions\Volo.Abp.Imaging.Abstractions.csproj", "{32F3E84B-D02E-42BD-BC5C-0D211564EF30}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Imaging.Abstractions", "src\Volo.Abp.Imaging.Abstractions\Volo.Abp.Imaging.Abstractions.csproj", "{32F3E84B-D02E-42BD-BC5C-0D211564EF30}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Imaging.AspNetCore", "src\Volo.Abp.Imaging.AspNetCore\Volo.Abp.Imaging.AspNetCore.csproj", "{78340A37-219E-4F2D-9AC6-40A7B467EEEC}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Imaging.AspNetCore", "src\Volo.Abp.Imaging.AspNetCore\Volo.Abp.Imaging.AspNetCore.csproj", "{78340A37-219E-4F2D-9AC6-40A7B467EEEC}"
@ -1325,6 +1327,10 @@ Global
{0858571B-CE73-4AD6-BD06-EC9F0714D8E9}.Debug|Any CPU.Build.0 = Debug|Any CPU {0858571B-CE73-4AD6-BD06-EC9F0714D8E9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0858571B-CE73-4AD6-BD06-EC9F0714D8E9}.Release|Any CPU.ActiveCfg = Release|Any CPU {0858571B-CE73-4AD6-BD06-EC9F0714D8E9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0858571B-CE73-4AD6-BD06-EC9F0714D8E9}.Release|Any CPU.Build.0 = Release|Any CPU {0858571B-CE73-4AD6-BD06-EC9F0714D8E9}.Release|Any CPU.Build.0 = Release|Any CPU
{86F3684C-A0A5-4943-8CFA-AE79E8E3E315}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{86F3684C-A0A5-4943-8CFA-AE79E8E3E315}.Debug|Any CPU.Build.0 = Debug|Any CPU
{86F3684C-A0A5-4943-8CFA-AE79E8E3E315}.Release|Any CPU.ActiveCfg = Release|Any CPU
{86F3684C-A0A5-4943-8CFA-AE79E8E3E315}.Release|Any CPU.Build.0 = Release|Any CPU
{32F3E84B-D02E-42BD-BC5C-0D211564EF30}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {32F3E84B-D02E-42BD-BC5C-0D211564EF30}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{32F3E84B-D02E-42BD-BC5C-0D211564EF30}.Debug|Any CPU.Build.0 = Debug|Any CPU {32F3E84B-D02E-42BD-BC5C-0D211564EF30}.Debug|Any CPU.Build.0 = Debug|Any CPU
{32F3E84B-D02E-42BD-BC5C-0D211564EF30}.Release|Any CPU.ActiveCfg = Release|Any CPU {32F3E84B-D02E-42BD-BC5C-0D211564EF30}.Release|Any CPU.ActiveCfg = Release|Any CPU
@ -1578,6 +1584,7 @@ Global
{8764DFAF-D13D-449A-9A5E-5D7F0B2D7FEF} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} {8764DFAF-D13D-449A-9A5E-5D7F0B2D7FEF} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
{0F80E95C-41E6-4F23-94FF-FC9D0B8D5D71} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} {0F80E95C-41E6-4F23-94FF-FC9D0B8D5D71} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
{0858571B-CE73-4AD6-BD06-EC9F0714D8E9} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} {0858571B-CE73-4AD6-BD06-EC9F0714D8E9} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
{86F3684C-A0A5-4943-8CFA-AE79E8E3E315} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
{32F3E84B-D02E-42BD-BC5C-0D211564EF30} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} {32F3E84B-D02E-42BD-BC5C-0D211564EF30} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
{44467427-E0BE-492C-B9B4-82B362C183C3} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} {44467427-E0BE-492C-B9B4-82B362C183C3} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
{F701EDA5-D7EA-4AA7-9C57-83ED50CE72EC} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} {F701EDA5-D7EA-4AA7-9C57-83ED50CE72EC} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}

4
framework/src/Volo.Abp.AspNetCore.Authentication.OpenIdConnect/Volo.Abp.AspNetCore.Authentication.OpenIdConnect.csproj

@ -8,10 +8,6 @@
<RootNamespace /> <RootNamespace />
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="$(MicrosoftAspNetCorePackageVersion)" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Volo.Abp.AspNetCore.MultiTenancy\Volo.Abp.AspNetCore.MultiTenancy.csproj" /> <ProjectReference Include="..\Volo.Abp.AspNetCore.MultiTenancy\Volo.Abp.AspNetCore.MultiTenancy.csproj" />
<ProjectReference Include="..\Volo.Abp.AspNetCore.Authentication.OAuth\Volo.Abp.AspNetCore.Authentication.OAuth.csproj" /> <ProjectReference Include="..\Volo.Abp.AspNetCore.Authentication.OAuth\Volo.Abp.AspNetCore.Authentication.OAuth.csproj" />

78
framework/src/Volo.Abp.AspNetCore.Components.Server/Microsoft/AspNetCore/Authentication/Cookies/CookieAuthenticationOptionsExtensions.cs

@ -1,7 +1,9 @@
using System; using System;
using System.Threading.Tasks;
using IdentityModel.Client; using IdentityModel.Client;
using Microsoft.AspNetCore.Authentication.OpenIdConnect; using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
namespace Microsoft.AspNetCore.Authentication.Cookies; namespace Microsoft.AspNetCore.Authentication.Cookies;
@ -16,41 +18,67 @@ public static class CookieAuthenticationOptionsExtensions
/// <returns></returns> /// <returns></returns>
public static CookieAuthenticationOptions IntrospectAccessToken(this CookieAuthenticationOptions options, string oidcAuthenticationScheme = "oidc") public static CookieAuthenticationOptions IntrospectAccessToken(this CookieAuthenticationOptions options, string oidcAuthenticationScheme = "oidc")
{ {
var originalHandler = options.Events.OnValidatePrincipal;
options.Events.OnValidatePrincipal = async principalContext => options.Events.OnValidatePrincipal = async principalContext =>
{ {
originalHandler?.Invoke(principalContext); if (principalContext.Principal == null || principalContext.Principal.Identity == null || !principalContext.Principal.Identity.IsAuthenticated)
{
return;
}
var logger = principalContext.HttpContext.RequestServices.GetRequiredService<ILogger<CookieAuthenticationOptions>>();
if (principalContext.Principal != null && principalContext.Principal.Identity != null && principalContext.Principal.Identity.IsAuthenticated) var accessToken = principalContext.Properties.GetTokenValue("access_token");
if (!accessToken.IsNullOrWhiteSpace())
{ {
var accessToken = principalContext.Properties.GetTokenValue("access_token"); var openIdConnectOptions = await GetOpenIdConnectOptions(principalContext, oidcAuthenticationScheme);
if (!accessToken.IsNullOrWhiteSpace()) var response = await openIdConnectOptions.Backchannel.IntrospectTokenAsync(new TokenIntrospectionRequest
{
Address = openIdConnectOptions.Configuration?.IntrospectionEndpoint ?? openIdConnectOptions.Authority.EnsureEndsWith('/') + "connect/introspect",
ClientId = openIdConnectOptions.ClientId,
ClientSecret = openIdConnectOptions.ClientSecret,
Token = accessToken
});
if (response.IsError)
{ {
var openIdConnectOptions = principalContext.HttpContext.RequestServices.GetRequiredService<IOptionsMonitor<OpenIdConnectOptions>>().Get(oidcAuthenticationScheme); logger.LogError(response.Error);
if (openIdConnectOptions.Configuration == null && openIdConnectOptions.ConfigurationManager != null) await SignOutAsync(principalContext);
{ return;
openIdConnectOptions.Configuration = await openIdConnectOptions.ConfigurationManager.GetConfigurationAsync(principalContext.HttpContext.RequestAborted);
}
var response = await openIdConnectOptions.Backchannel.IntrospectTokenAsync(new TokenIntrospectionRequest
{
Address = openIdConnectOptions.Configuration?.IntrospectionEndpoint ?? openIdConnectOptions.Authority.EnsureEndsWith('/') + "connect/introspect",
ClientId = openIdConnectOptions.ClientId,
ClientSecret = openIdConnectOptions.ClientSecret,
Token = accessToken
});
if (response.IsActive)
{
return;
}
} }
principalContext.RejectPrincipal(); if (!response.IsActive)
await principalContext.HttpContext.SignOutAsync(principalContext.Scheme.Name); {
logger.LogError("The access_token is not active.");
await SignOutAsync(principalContext);
return;
}
logger.LogInformation("The access_token is active.");
}
else
{
logger.LogError("The access_token is not found in the cookie properties, Please make sure SaveTokens of OpenIdConnectOptions is set as true.");
await SignOutAsync(principalContext);
} }
}; };
return options; return options;
} }
private async static Task<OpenIdConnectOptions> GetOpenIdConnectOptions(CookieValidatePrincipalContext principalContext, string oidcAuthenticationScheme)
{
var openIdConnectOptions = principalContext.HttpContext.RequestServices.GetRequiredService<IOptionsMonitor<OpenIdConnectOptions>>().Get(oidcAuthenticationScheme);
if (openIdConnectOptions.Configuration == null && openIdConnectOptions.ConfigurationManager != null)
{
openIdConnectOptions.Configuration = await openIdConnectOptions.ConfigurationManager.GetConfigurationAsync(principalContext.HttpContext.RequestAborted);
}
return openIdConnectOptions;
}
private async static Task SignOutAsync(CookieValidatePrincipalContext principalContext)
{
principalContext.RejectPrincipal();
await principalContext.HttpContext.SignOutAsync(principalContext.Scheme.Name);
}
} }

1
framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo.Abp.AspNetCore.Components.WebAssembly.csproj

@ -23,6 +23,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="$(MicrosoftAspNetCorePackageVersion)" /> <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="$(MicrosoftAspNetCorePackageVersion)" />
<PackageReference Include="Microsoft.AspNetCore.Components.Authorization" Version="$(MicrosoftAspNetCorePackageVersion)" /> <PackageReference Include="Microsoft.AspNetCore.Components.Authorization" Version="$(MicrosoftAspNetCorePackageVersion)" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" Version="$(MicrosoftAspNetCorePackageVersion)" />
<PackageReference Include="Microsoft.AspNetCore.WebUtilities" Version="2.2.0" /> <PackageReference Include="Microsoft.AspNetCore.WebUtilities" Version="2.2.0" />
</ItemGroup> </ItemGroup>

2
framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/AbpAspNetCoreComponentsWebAssemblyModule.cs

@ -19,7 +19,7 @@ namespace Volo.Abp.AspNetCore.Components.WebAssembly;
typeof(AbpAspNetCoreMvcClientCommonModule), typeof(AbpAspNetCoreMvcClientCommonModule),
typeof(AbpUiModule), typeof(AbpUiModule),
typeof(AbpAspNetCoreComponentsWebModule) typeof(AbpAspNetCoreComponentsWebModule)
)] )]
public class AbpAspNetCoreComponentsWebAssemblyModule : AbpModule public class AbpAspNetCoreComponentsWebAssemblyModule : AbpModule
{ {
public override void PreConfigureServices(ServiceConfigurationContext context) public override void PreConfigureServices(ServiceConfigurationContext context)

40
framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/ClientProxyExceptionEventHandler.cs

@ -0,0 +1,40 @@
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.WebAssembly.Authentication;
using Volo.Abp.DependencyInjection;
using Volo.Abp.EventBus;
using Volo.Abp.Http;
namespace Volo.Abp.AspNetCore.Components.WebAssembly;
public class ClientProxyExceptionEventHandler : ILocalEventHandler<ClientProxyExceptionEventData>, ITransientDependency
{
protected NavigationManager NavigationManager { get; }
protected IAccessTokenProvider AccessTokenProvider { get; }
public ClientProxyExceptionEventHandler(NavigationManager navigationManager, IAccessTokenProvider accessTokenProvider)
{
NavigationManager = navigationManager;
AccessTokenProvider = accessTokenProvider;
}
public virtual async Task HandleEventAsync(ClientProxyExceptionEventData eventData)
{
if (eventData.StatusCode == 401)
{
var result = await AccessTokenProvider.RequestAccessToken();
if (result.Status != AccessTokenResultStatus.Success)
{
NavigationManager.NavigateToLogout("authentication/logout");
return;
}
result.TryGetToken(out var token);
if (token != null && DateTimeOffset.Now >= token.Expires.AddMinutes(-5))
{
NavigationManager.NavigateToLogout("authentication/logout");
}
}
}
}

1
framework/src/Volo.Abp.AspNetCore.Components/Volo.Abp.AspNetCore.Components.csproj

@ -18,6 +18,7 @@
<ProjectReference Include="..\Volo.Abp.Timing\Volo.Abp.Timing.csproj" /> <ProjectReference Include="..\Volo.Abp.Timing\Volo.Abp.Timing.csproj" />
<ProjectReference Include="..\Volo.Abp.ObjectMapping\Volo.Abp.ObjectMapping.csproj" /> <ProjectReference Include="..\Volo.Abp.ObjectMapping\Volo.Abp.ObjectMapping.csproj" />
<ProjectReference Include="..\Volo.Abp.Security\Volo.Abp.Security.csproj" /> <ProjectReference Include="..\Volo.Abp.Security\Volo.Abp.Security.csproj" />
<ProjectReference Include="..\Volo.Abp.MultiTenancy.Abstractions\Volo.Abp.MultiTenancy.Abstractions.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

4
framework/src/Volo.Abp.AspNetCore.Components/Volo/Abp/AspNetCore/Components/AbpAspNetCoreComponentsModule.cs

@ -4,6 +4,7 @@ using Volo.Abp.AspNetCore.Components.DependencyInjection;
using Volo.Abp.DynamicProxy; using Volo.Abp.DynamicProxy;
using Volo.Abp.Localization; using Volo.Abp.Localization;
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
using Volo.Abp.MultiTenancy;
using Volo.Abp.ObjectMapping; using Volo.Abp.ObjectMapping;
using Volo.Abp.Security; using Volo.Abp.Security;
using Volo.Abp.Timing; using Volo.Abp.Timing;
@ -13,7 +14,8 @@ namespace Volo.Abp.AspNetCore.Components;
[DependsOn( [DependsOn(
typeof(AbpObjectMappingModule), typeof(AbpObjectMappingModule),
typeof(AbpSecurityModule), typeof(AbpSecurityModule),
typeof(AbpTimingModule) typeof(AbpTimingModule),
typeof(AbpMultiTenancyAbstractionsModule)
)] )]
public class AbpAspNetCoreComponentsModule : AbpModule public class AbpAspNetCoreComponentsModule : AbpModule
{ {

3
framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcOptions.cs

@ -12,6 +12,8 @@ public class AbpAspNetCoreMvcOptions
public HashSet<Type> IgnoredControllersOnModelExclusion { get; } public HashSet<Type> IgnoredControllersOnModelExclusion { get; }
public HashSet<Type> ControllersToRemove { get; }
public bool AutoModelValidation { get; set; } public bool AutoModelValidation { get; set; }
public bool EnableRazorRuntimeCompilationOnDevelopment { get; set; } public bool EnableRazorRuntimeCompilationOnDevelopment { get; set; }
@ -22,6 +24,7 @@ public class AbpAspNetCoreMvcOptions
{ {
ConventionalControllers = new AbpConventionalControllerOptions(); ConventionalControllers = new AbpConventionalControllerOptions();
IgnoredControllersOnModelExclusion = new HashSet<Type>(); IgnoredControllersOnModelExclusion = new HashSet<Type>();
ControllersToRemove = new HashSet<Type>();
AutoModelValidation = true; AutoModelValidation = true;
EnableRazorRuntimeCompilationOnDevelopment = true; EnableRazorRuntimeCompilationOnDevelopment = true;
ChangeControllerModelApiExplorerGroupName = true; ChangeControllerModelApiExplorerGroupName = true;

38
framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Conventions/AbpServiceConvention.cs

@ -11,6 +11,7 @@ using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Volo.Abp.Application.Services; using Volo.Abp.Application.Services;
using Volo.Abp.AspNetCore.Controllers;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
using Volo.Abp.GlobalFeatures; using Volo.Abp.GlobalFeatures;
using Volo.Abp.Http; using Volo.Abp.Http;
@ -80,6 +81,36 @@ public class AbpServiceConvention : IAbpServiceConvention, ITransientDependency
{ {
var controllerModelsToRemove = new List<ControllerModel>(); var controllerModelsToRemove = new List<ControllerModel>();
if (Options.ControllersToRemove.Any())
{
var removeControllerModels = GetControllers(application)
.Where(cm => Options.ControllersToRemove.Contains(cm.ControllerType))
.ToArray();
if (removeControllerModels.Any())
{
controllerModelsToRemove.AddRange(removeControllerModels);
Logger.LogInformation($"Removing the controller{(removeControllerModels.Length > 1 ? "s" : "")} {removeControllerModels.Select(c => c.ControllerType.AssemblyQualifiedName).JoinAsString(", ")} from the application model");
}
}
foreach (var controllerModel in GetControllers(application))
{
var replaceControllersAttr = ReflectionHelper.GetSingleAttributeOrDefault<ReplaceControllersAttribute>(controllerModel.ControllerType);
if (replaceControllersAttr != default)
{
var replaceControllerModels = GetControllers(application)
.Where(cm => replaceControllersAttr.ControllerTypes.Contains(cm.ControllerType))
.ToArray();
if (replaceControllerModels.Any())
{
controllerModelsToRemove.AddRange(replaceControllerModels);
Logger.LogInformation($"Removing the controller{(replaceControllerModels.Length > 1 ? "s" : "")} {replaceControllersAttr.ControllerTypes.Select(c => c.AssemblyQualifiedName).JoinAsString(", ")} from the application model since {(replaceControllerModels.Length > 1 ? "they are" : "it is")} replaced by the controller: {controllerModel.ControllerType.AssemblyQualifiedName}");
}
}
}
foreach (var controllerModel in GetControllers(application)) foreach (var controllerModel in GetControllers(application))
{ {
if (!controllerModel.ControllerType.IsDefined(typeof(ExposeServicesAttribute), false)) if (!controllerModel.ControllerType.IsDefined(typeof(ExposeServicesAttribute), false))
@ -99,8 +130,11 @@ public class AbpServiceConvention : IAbpServiceConvention, ITransientDependency
.Where(cm => exposeServicesAttr.ServiceTypes.Contains(cm.ControllerType)) .Where(cm => exposeServicesAttr.ServiceTypes.Contains(cm.ControllerType))
.ToArray(); .ToArray();
controllerModelsToRemove.AddRange(exposedControllerModels); if (exposedControllerModels.Any())
Logger.LogInformation($"Removing the controller{(exposedControllerModels.Length > 1 ? "s" : "")} {exposeServicesAttr.ServiceTypes.Select(c => c.AssemblyQualifiedName).JoinAsString(", ")} from the application model since {(exposedControllerModels.Length > 1 ? "they are" : "it is")} replaced by the controller: {controllerModel.ControllerType.AssemblyQualifiedName}"); {
controllerModelsToRemove.AddRange(exposedControllerModels);
Logger.LogInformation($"Removing the controller{(exposedControllerModels.Length > 1 ? "s" : "")} {exposeServicesAttr.ServiceTypes.Select(c => c.AssemblyQualifiedName).JoinAsString(", ")} from the application model since {(exposedControllerModels.Length > 1 ? "they are" : "it is")} replaced by the controller: {controllerModel.ControllerType.AssemblyQualifiedName}");
}
continue; continue;
} }

100
framework/src/Volo.Abp.AspNetCore/Microsoft/Extensions/DependencyInjection/CookieAuthenticationOptionsExtensions.cs

@ -0,0 +1,100 @@
using System;
using System.Globalization;
using System.Threading.Tasks;
using IdentityModel.Client;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
namespace Microsoft.Extensions.DependencyInjection;
public static class CookieAuthenticationOptionsExtensions
{
/// <summary>
/// Check the access_token is expired or inactive.
/// </summary>
public static CookieAuthenticationOptions CheckTokenExpiration(this CookieAuthenticationOptions options, string oidcAuthenticationScheme = "oidc", TimeSpan? advance = null, TimeSpan? validationInterval = null)
{
advance ??= TimeSpan.FromMinutes(3);
validationInterval ??= TimeSpan.FromMinutes(1);
options.Events.OnValidatePrincipal = async principalContext =>
{
if (principalContext.Principal == null || principalContext.Principal.Identity == null || !principalContext.Principal.Identity.IsAuthenticated)
{
return;
}
var logger = principalContext.HttpContext.RequestServices.GetRequiredService<ILogger<CookieAuthenticationOptions>>();
var tokenExpiresAt = principalContext.Properties.Items[".Token.expires_at"];
if (DateTimeOffset.TryParseExact(tokenExpiresAt, "o", null, DateTimeStyles.RoundtripKind, out var expiresAt) &&
expiresAt < DateTimeOffset.UtcNow.Subtract(advance.Value))
{
logger.LogInformation("The access_token is expired.");
await SignOutAsync(principalContext);
return;
}
if (principalContext.Properties.IssuedUtc != null && DateTimeOffset.UtcNow.Subtract(principalContext.Properties.IssuedUtc.Value) > validationInterval)
{
logger.LogInformation($"Check the access_token is active every {validationInterval.Value.TotalSeconds} seconds.");
var accessToken = principalContext.Properties.GetTokenValue("access_token");
if (!accessToken.IsNullOrWhiteSpace())
{
var openIdConnectOptions = await GetOpenIdConnectOptions(principalContext, oidcAuthenticationScheme);
var response = await openIdConnectOptions.Backchannel.IntrospectTokenAsync(new TokenIntrospectionRequest
{
Address = openIdConnectOptions.Configuration?.IntrospectionEndpoint ?? openIdConnectOptions.Authority.EnsureEndsWith('/') + "connect/introspect",
ClientId = openIdConnectOptions.ClientId,
ClientSecret = openIdConnectOptions.ClientSecret,
Token = accessToken
});
if (response.IsError)
{
logger.LogError(response.Error);
await SignOutAsync(principalContext);
return;
}
if (!response.IsActive)
{
logger.LogError("The access_token is not active.");
await SignOutAsync(principalContext);
return;
}
logger.LogInformation("The access_token is active.");
principalContext.ShouldRenew = true;
}
else
{
logger.LogError("The access_token is not found in the cookie properties, Please make sure SaveTokens of OpenIdConnectOptions is set as true.");
await SignOutAsync(principalContext);
}
}
};
return options;
}
private async static Task<OpenIdConnectOptions> GetOpenIdConnectOptions(CookieValidatePrincipalContext principalContext, string oidcAuthenticationScheme)
{
var openIdConnectOptions = principalContext.HttpContext.RequestServices.GetRequiredService<IOptionsMonitor<OpenIdConnectOptions>>().Get(oidcAuthenticationScheme);
if (openIdConnectOptions.Configuration == null && openIdConnectOptions.ConfigurationManager != null)
{
openIdConnectOptions.Configuration = await openIdConnectOptions.ConfigurationManager.GetConfigurationAsync(principalContext.HttpContext.RequestAborted);
}
return openIdConnectOptions;
}
private async static Task SignOutAsync(CookieValidatePrincipalContext principalContext)
{
principalContext.RejectPrincipal();
await principalContext.HttpContext.SignOutAsync(principalContext.Scheme.Name);
}
}

2
framework/src/Volo.Abp.AspNetCore/Volo.Abp.AspNetCore.csproj

@ -26,6 +26,8 @@
<ProjectReference Include="..\Volo.Abp.Uow\Volo.Abp.Uow.csproj" /> <ProjectReference Include="..\Volo.Abp.Uow\Volo.Abp.Uow.csproj" />
<ProjectReference Include="..\Volo.Abp.Validation\Volo.Abp.Validation.csproj" /> <ProjectReference Include="..\Volo.Abp.Validation\Volo.Abp.Validation.csproj" />
<ProjectReference Include="..\Volo.Abp.VirtualFileSystem\Volo.Abp.VirtualFileSystem.csproj" /> <ProjectReference Include="..\Volo.Abp.VirtualFileSystem\Volo.Abp.VirtualFileSystem.csproj" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="$(MicrosoftAspNetCorePackageVersion)" />
<PackageReference Include="IdentityModel" Version="6.0.0" />
</ItemGroup> </ItemGroup>
</Project> </Project>

14
framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Controllers/ReplaceControllersAttribute.cs

@ -0,0 +1,14 @@
using System;
namespace Volo.Abp.AspNetCore.Controllers;
[AttributeUsage(AttributeTargets.Class)]
public class ReplaceControllersAttribute : Attribute
{
public Type[] ControllerTypes { get; }
public ReplaceControllersAttribute(params Type[] controllerTypes)
{
ControllerTypes = controllerTypes ?? Type.EmptyTypes;
}
}

2
framework/src/Volo.Abp.Authorization.Abstractions/Volo.Abp.Authorization.Abstractions.csproj

@ -19,7 +19,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Volo.Abp.MultiTenancy\Volo.Abp.MultiTenancy.csproj" /> <ProjectReference Include="..\Volo.Abp.MultiTenancy.Abstractions\Volo.Abp.MultiTenancy.Abstractions.csproj" />
</ItemGroup> </ItemGroup>
</Project> </Project>

2
framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/AbpAuthorizationAbstractionsModule.cs

@ -4,7 +4,7 @@ using Volo.Abp.MultiTenancy;
namespace Volo.Abp.Authorization; namespace Volo.Abp.Authorization;
[DependsOn( [DependsOn(
typeof(AbpMultiTenancyModule) typeof(AbpMultiTenancyAbstractionsModule)
)] )]
public class AbpAuthorizationAbstractionsModule : AbpModule public class AbpAuthorizationAbstractionsModule : AbpModule
{ {

4
framework/src/Volo.Abp.Authorization/Volo.Abp.Authorization.csproj

@ -20,11 +20,13 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Volo.Abp.Authorization.Abstractions\Volo.Abp.Authorization.Abstractions.csproj" /> <ProjectReference Include="..\Volo.Abp.Authorization.Abstractions\Volo.Abp.Authorization.Abstractions.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Volo.Abp.Localization\Volo.Abp.Localization.csproj" /> <ProjectReference Include="..\Volo.Abp.Localization\Volo.Abp.Localization.csproj" />
<ProjectReference Include="..\Volo.Abp.MultiTenancy\Volo.Abp.MultiTenancy.csproj" />
<ProjectReference Include="..\Volo.Abp.Security\Volo.Abp.Security.csproj" /> <ProjectReference Include="..\Volo.Abp.Security\Volo.Abp.Security.csproj" />
</ItemGroup> </ItemGroup>

4
framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AbpAuthorizationModule.cs

@ -8,6 +8,7 @@ using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Localization; using Volo.Abp.Localization;
using Volo.Abp.Localization.ExceptionHandling; using Volo.Abp.Localization.ExceptionHandling;
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
using Volo.Abp.MultiTenancy;
using Volo.Abp.Security; using Volo.Abp.Security;
using Volo.Abp.VirtualFileSystem; using Volo.Abp.VirtualFileSystem;
@ -16,7 +17,8 @@ namespace Volo.Abp.Authorization;
[DependsOn( [DependsOn(
typeof(AbpAuthorizationAbstractionsModule), typeof(AbpAuthorizationAbstractionsModule),
typeof(AbpSecurityModule), typeof(AbpSecurityModule),
typeof(AbpLocalizationModule) typeof(AbpLocalizationModule),
typeof(AbpMultiTenancyModule)
)] )]
public class AbpAuthorizationModule : AbpModule public class AbpAuthorizationModule : AbpModule
{ {

1
framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo.Abp.BackgroundJobs.Abstractions.csproj

@ -16,6 +16,7 @@
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Volo.Abp.Json\Volo.Abp.Json.csproj" /> <ProjectReference Include="..\Volo.Abp.Json\Volo.Abp.Json.csproj" />
<ProjectReference Include="..\Volo.Abp.MultiTenancy.Abstractions\Volo.Abp.MultiTenancy.Abstractions.csproj" />
</ItemGroup> </ItemGroup>
</Project> </Project>

4
framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/AbpBackgroundJobsAbstractionsModule.cs

@ -3,12 +3,14 @@ using System.Collections.Generic;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Json; using Volo.Abp.Json;
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
using Volo.Abp.MultiTenancy;
using Volo.Abp.Reflection; using Volo.Abp.Reflection;
namespace Volo.Abp.BackgroundJobs; namespace Volo.Abp.BackgroundJobs;
[DependsOn( [DependsOn(
typeof(AbpJsonModule) typeof(AbpJsonModule),
typeof(AbpMultiTenancyAbstractionsModule)
)] )]
public class AbpBackgroundJobsAbstractionsModule : AbpModule public class AbpBackgroundJobsAbstractionsModule : AbpModule
{ {

1
framework/src/Volo.Abp.BackgroundJobs/Volo.Abp.BackgroundJobs.csproj

@ -19,6 +19,7 @@
<ProjectReference Include="..\Volo.Abp.BackgroundWorkers\Volo.Abp.BackgroundWorkers.csproj" /> <ProjectReference Include="..\Volo.Abp.BackgroundWorkers\Volo.Abp.BackgroundWorkers.csproj" />
<ProjectReference Include="..\Volo.Abp.DistributedLocking.Abstractions\Volo.Abp.DistributedLocking.Abstractions.csproj" /> <ProjectReference Include="..\Volo.Abp.DistributedLocking.Abstractions\Volo.Abp.DistributedLocking.Abstractions.csproj" />
<ProjectReference Include="..\Volo.Abp.Guids\Volo.Abp.Guids.csproj" /> <ProjectReference Include="..\Volo.Abp.Guids\Volo.Abp.Guids.csproj" />
<ProjectReference Include="..\Volo.Abp.MultiTenancy\Volo.Abp.MultiTenancy.csproj" />
<ProjectReference Include="..\Volo.Abp.Timing\Volo.Abp.Timing.csproj" /> <ProjectReference Include="..\Volo.Abp.Timing\Volo.Abp.Timing.csproj" />
</ItemGroup> </ItemGroup>

4
framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/AbpBackgroundJobsModule.cs

@ -6,6 +6,7 @@ using Volo.Abp.Data;
using Volo.Abp.DistributedLocking; using Volo.Abp.DistributedLocking;
using Volo.Abp.Guids; using Volo.Abp.Guids;
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
using Volo.Abp.MultiTenancy;
using Volo.Abp.Threading; using Volo.Abp.Threading;
using Volo.Abp.Timing; using Volo.Abp.Timing;
@ -16,7 +17,8 @@ namespace Volo.Abp.BackgroundJobs;
typeof(AbpBackgroundWorkersModule), typeof(AbpBackgroundWorkersModule),
typeof(AbpTimingModule), typeof(AbpTimingModule),
typeof(AbpGuidsModule), typeof(AbpGuidsModule),
typeof(AbpDistributedLockingAbstractionsModule) typeof(AbpDistributedLockingAbstractionsModule),
typeof(AbpMultiTenancyModule)
)] )]
public class AbpBackgroundJobsModule : AbpModule public class AbpBackgroundJobsModule : AbpModule
{ {

8
framework/src/Volo.Abp.BlazoriseUI/Volo.Abp.BlazoriseUI.csproj

@ -14,10 +14,10 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Blazorise" Version="1.2.0" /> <PackageReference Include="Blazorise" Version="1.2.3" />
<PackageReference Include="Blazorise.DataGrid" Version="1.2.0" /> <PackageReference Include="Blazorise.DataGrid" Version="1.2.3" />
<PackageReference Include="Blazorise.Snackbar" Version="1.2.0" /> <PackageReference Include="Blazorise.Snackbar" Version="1.2.3" />
<PackageReference Include="Blazorise.Components" Version="1.2.0" /> <PackageReference Include="Blazorise.Components" Version="1.2.3" />
</ItemGroup> </ItemGroup>
</Project> </Project>

2
framework/src/Volo.Abp.Caching.StackExchangeRedis/Volo.Abp.Caching.StackExchangeRedis.csproj

@ -5,6 +5,8 @@
<PropertyGroup> <PropertyGroup>
<TargetFrameworks>netstandard2.0;netstandard2.1;net7.0</TargetFrameworks> <TargetFrameworks>netstandard2.0;netstandard2.1;net7.0</TargetFrameworks>
<Nullable>enable</Nullable>
<WarningsAsErrors>Nullable</WarningsAsErrors>
<AssemblyName>Volo.Abp.Caching.StackExchangeRedis</AssemblyName> <AssemblyName>Volo.Abp.Caching.StackExchangeRedis</AssemblyName>
<PackageId>Volo.Abp.Caching.StackExchangeRedis</PackageId> <PackageId>Volo.Abp.Caching.StackExchangeRedis</PackageId>
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback> <AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback>

2
framework/src/Volo.Abp.Caching.StackExchangeRedis/Volo/Abp/Caching/StackExchangeRedis/AbpCachingStackExchangeRedisModule.cs

@ -16,7 +16,7 @@ public class AbpCachingStackExchangeRedisModule : AbpModule
var configuration = context.Services.GetConfiguration(); var configuration = context.Services.GetConfiguration();
var redisEnabled = configuration["Redis:IsEnabled"]; var redisEnabled = configuration["Redis:IsEnabled"];
if (redisEnabled.IsNullOrEmpty() || bool.Parse(redisEnabled)) if (string.IsNullOrEmpty(redisEnabled) || bool.Parse(redisEnabled))
{ {
context.Services.AddStackExchangeRedisCache(options => context.Services.AddStackExchangeRedisCache(options =>
{ {

60
framework/src/Volo.Abp.Caching.StackExchangeRedis/Volo/Abp/Caching/StackExchangeRedis/AbpRedisCache.cs

@ -28,8 +28,8 @@ public class AbpRedisCache : RedisCache, ICacheSupportsMultipleItems
private readonly static MethodInfo GetAbsoluteExpirationMethod; private readonly static MethodInfo GetAbsoluteExpirationMethod;
private readonly static MethodInfo GetExpirationInSecondsMethod; private readonly static MethodInfo GetExpirationInSecondsMethod;
protected IDatabase RedisDatabase => GetRedisDatabase(); protected IDatabase RedisDatabase => GetRedisDatabase()!;
private IDatabase _redisDatabase; private IDatabase? _redisDatabase;
protected string Instance { get; } protected string Instance { get; }
@ -37,28 +37,27 @@ public class AbpRedisCache : RedisCache, ICacheSupportsMultipleItems
{ {
var type = typeof(RedisCache); var type = typeof(RedisCache);
RedisDatabaseField = Check.NotNull(type.GetField("_cache", BindingFlags.Instance | BindingFlags.NonPublic), nameof(RedisDatabaseField)); RedisDatabaseField = Check.NotNull(type.GetField("_cache", BindingFlags.Instance | BindingFlags.NonPublic), nameof(RedisDatabaseField))!;
SetScriptField = Check.NotNull(type.GetField("_setScript", BindingFlags.Instance | BindingFlags.NonPublic), nameof(SetScriptField)); SetScriptField = Check.NotNull(type.GetField("_setScript", BindingFlags.Instance | BindingFlags.NonPublic), nameof(SetScriptField))!;
ConnectMethod = Check.NotNull(type.GetMethod("Connect", BindingFlags.Instance | BindingFlags.NonPublic), nameof(ConnectMethod))!;
ConnectMethod = Check.NotNull(type.GetMethod("Connect", BindingFlags.Instance | BindingFlags.NonPublic), nameof(ConnectMethod)); ConnectAsyncMethod = Check.NotNull(type.GetMethod("ConnectAsync", BindingFlags.Instance | BindingFlags.NonPublic), nameof(ConnectAsyncMethod))!;
ConnectAsyncMethod = Check.NotNull(type.GetMethod("ConnectAsync", BindingFlags.Instance | BindingFlags.NonPublic), nameof(ConnectAsyncMethod)); MapMetadataMethod = Check.NotNull(type.GetMethod("MapMetadata", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Static), nameof(MapMetadataMethod))!;
MapMetadataMethod = Check.NotNull(type.GetMethod("MapMetadata", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Static), nameof(MapMetadataMethod)); GetAbsoluteExpirationMethod = Check.NotNull(type.GetMethod("GetAbsoluteExpiration", BindingFlags.Static | BindingFlags.NonPublic), nameof(GetAbsoluteExpirationMethod))!;
GetAbsoluteExpirationMethod = Check.NotNull(type.GetMethod("GetAbsoluteExpiration", BindingFlags.Static | BindingFlags.NonPublic), nameof(GetAbsoluteExpirationMethod)); GetExpirationInSecondsMethod = Check.NotNull(type.GetMethod("GetExpirationInSeconds", BindingFlags.Static | BindingFlags.NonPublic), nameof(GetExpirationInSecondsMethod))!;
GetExpirationInSecondsMethod = Check.NotNull(type.GetMethod("GetExpirationInSeconds", BindingFlags.Static | BindingFlags.NonPublic), nameof(GetExpirationInSecondsMethod)); AbsoluteExpirationKey = type.GetField("AbsoluteExpirationKey", BindingFlags.Static | BindingFlags.NonPublic)!.GetValue(null)!.ToString()!;
AbsoluteExpirationKey = type.GetField("AbsoluteExpirationKey", BindingFlags.Static | BindingFlags.NonPublic)?.GetValue(null).ToString(); SlidingExpirationKey = type.GetField("SlidingExpirationKey", BindingFlags.Static | BindingFlags.NonPublic)!.GetValue(null)!.ToString()!;
SlidingExpirationKey = type.GetField("SlidingExpirationKey", BindingFlags.Static | BindingFlags.NonPublic)?.GetValue(null).ToString(); DataKey = type.GetField("DataKey", BindingFlags.Static | BindingFlags.NonPublic)!.GetValue(null)!.ToString()!;
DataKey = type.GetField("DataKey", BindingFlags.Static | BindingFlags.NonPublic)?.GetValue(null).ToString(); NotPresent = type.GetField("NotPresent", BindingFlags.Static | BindingFlags.NonPublic)!.GetValue(null)!.To<int>();
// ReSharper disable once PossibleNullReferenceException
NotPresent = Check.NotNull(type.GetField("NotPresent", BindingFlags.Static | BindingFlags.NonPublic), nameof(NotPresent)).GetValue(null).To<int>();
} }
public AbpRedisCache(IOptions<RedisCacheOptions> optionsAccessor) public AbpRedisCache(IOptions<RedisCacheOptions> optionsAccessor)
@ -84,10 +83,10 @@ public class AbpRedisCache : RedisCache, ICacheSupportsMultipleItems
return; return;
} }
await (Task)ConnectAsyncMethod.Invoke(this, new object[] { token }); await (Task)ConnectAsyncMethod.Invoke(this, new object[] { token })!;
} }
public byte[][] GetMany( public byte[]?[] GetMany(
IEnumerable<string> keys) IEnumerable<string> keys)
{ {
keys = Check.NotNull(keys, nameof(keys)); keys = Check.NotNull(keys, nameof(keys));
@ -95,7 +94,7 @@ public class AbpRedisCache : RedisCache, ICacheSupportsMultipleItems
return GetAndRefreshMany(keys, true); return GetAndRefreshMany(keys, true);
} }
public async Task<byte[][]> GetManyAsync( public async Task<byte[]?[]> GetManyAsync(
IEnumerable<string> keys, IEnumerable<string> keys,
CancellationToken token = default) CancellationToken token = default)
{ {
@ -161,7 +160,7 @@ public class AbpRedisCache : RedisCache, ICacheSupportsMultipleItems
await RedisDatabase.KeyDeleteAsync(keys.Select(key => (RedisKey)(Instance + key)).ToArray()); await RedisDatabase.KeyDeleteAsync(keys.Select(key => (RedisKey)(Instance + key)).ToArray());
} }
protected virtual byte[][] GetAndRefreshMany( protected virtual byte[]?[] GetAndRefreshMany(
IEnumerable<string> keys, IEnumerable<string> keys,
bool getData) bool getData)
{ {
@ -186,7 +185,7 @@ public class AbpRedisCache : RedisCache, ICacheSupportsMultipleItems
return bytes; return bytes;
} }
protected virtual async Task<byte[][]> GetAndRefreshManyAsync( protected virtual async Task<byte[]?[]> GetAndRefreshManyAsync(
IEnumerable<string> keys, IEnumerable<string> keys,
bool getData, bool getData,
CancellationToken token = default) CancellationToken token = default)
@ -217,7 +216,7 @@ public class AbpRedisCache : RedisCache, ICacheSupportsMultipleItems
protected virtual Task[] PipelineRefreshManyAndOutData( protected virtual Task[] PipelineRefreshManyAndOutData(
string[] keys, string[] keys,
RedisValue[][] results, RedisValue[][] results,
out byte[][] bytes) out byte[]?[] bytes)
{ {
bytes = new byte[keys.Length][]; bytes = new byte[keys.Length][];
var tasks = new Task[keys.Length]; var tasks = new Task[keys.Length];
@ -226,7 +225,7 @@ public class AbpRedisCache : RedisCache, ICacheSupportsMultipleItems
{ {
if (results[i].Length >= 2) if (results[i].Length >= 2)
{ {
MapMetadata(results[i], out DateTimeOffset? absExpr, out TimeSpan? sldExpr); MapMetadata(results[i], out var absExpr, out var sldExpr);
if (sldExpr.HasValue) if (sldExpr.HasValue)
{ {
@ -295,7 +294,7 @@ public class AbpRedisCache : RedisCache, ICacheSupportsMultipleItems
out DateTimeOffset? absoluteExpiration, out DateTimeOffset? absoluteExpiration,
out TimeSpan? slidingExpiration) out TimeSpan? slidingExpiration)
{ {
var parameters = new object[] { results, null, null }; var parameters = new object?[] { results, null, null };
MapMetadataMethod.Invoke(this, parameters); MapMetadataMethod.Invoke(this, parameters);
absoluteExpiration = (DateTimeOffset?)parameters[1]; absoluteExpiration = (DateTimeOffset?)parameters[1];
@ -308,7 +307,7 @@ public class AbpRedisCache : RedisCache, ICacheSupportsMultipleItems
DistributedCacheEntryOptions options) DistributedCacheEntryOptions options)
{ {
return (long?)GetExpirationInSecondsMethod.Invoke(null, return (long?)GetExpirationInSecondsMethod.Invoke(null,
new object[] { creationTime, absoluteExpiration, options }); new object?[] { creationTime, absoluteExpiration, options });
} }
protected virtual DateTimeOffset? GetAbsoluteExpiration( protected virtual DateTimeOffset? GetAbsoluteExpiration(
@ -318,18 +317,13 @@ public class AbpRedisCache : RedisCache, ICacheSupportsMultipleItems
return (DateTimeOffset?)GetAbsoluteExpirationMethod.Invoke(null, new object[] { creationTime, options }); return (DateTimeOffset?)GetAbsoluteExpirationMethod.Invoke(null, new object[] { creationTime, options });
} }
private IDatabase GetRedisDatabase() private IDatabase? GetRedisDatabase()
{ {
if (_redisDatabase == null) return _redisDatabase ??= RedisDatabaseField.GetValue(this) as IDatabase;
{
_redisDatabase = RedisDatabaseField.GetValue(this) as IDatabase;
}
return _redisDatabase;
} }
private string GetSetScript() private string GetSetScript()
{ {
return SetScriptField?.GetValue(this).ToString(); return SetScriptField.GetValue(this)!.ToString()!;
} }
} }

1
framework/src/Volo.Abp.Caching/Volo.Abp.Caching.csproj

@ -5,6 +5,7 @@
<PropertyGroup> <PropertyGroup>
<TargetFrameworks>netstandard2.0;netstandard2.1;net7.0</TargetFrameworks> <TargetFrameworks>netstandard2.0;netstandard2.1;net7.0</TargetFrameworks>
<Nullable>enable</Nullable>
<AssemblyName>Volo.Abp.Caching</AssemblyName> <AssemblyName>Volo.Abp.Caching</AssemblyName>
<PackageId>Volo.Abp.Caching</PackageId> <PackageId>Volo.Abp.Caching</PackageId>
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback> <AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback>

10
framework/src/Volo.Abp.Caching/Volo/Abp/Caching/AbpDistributedCacheOptions.cs

@ -25,26 +25,26 @@ public class AbpDistributedCacheOptions
/// List of all cache configurators. /// List of all cache configurators.
/// (func argument:Name of cache) /// (func argument:Name of cache)
/// </summary> /// </summary>
public List<Func<string, DistributedCacheEntryOptions>> CacheConfigurators { get; set; } //TODO: use a configurator interface instead? public List<Func<string, DistributedCacheEntryOptions?>> CacheConfigurators { get; set; } //TODO: use a configurator interface instead?
public AbpDistributedCacheOptions() public AbpDistributedCacheOptions()
{ {
CacheConfigurators = new List<Func<string, DistributedCacheEntryOptions>>(); CacheConfigurators = new List<Func<string, DistributedCacheEntryOptions?>>();
GlobalCacheEntryOptions = new DistributedCacheEntryOptions(); GlobalCacheEntryOptions = new DistributedCacheEntryOptions();
KeyPrefix = ""; KeyPrefix = "";
} }
public void ConfigureCache<TCacheItem>(DistributedCacheEntryOptions options) public void ConfigureCache<TCacheItem>(DistributedCacheEntryOptions? options)
{ {
ConfigureCache(typeof(TCacheItem), options); ConfigureCache(typeof(TCacheItem), options);
} }
public void ConfigureCache(Type cacheItemType, DistributedCacheEntryOptions options) public void ConfigureCache(Type cacheItemType, DistributedCacheEntryOptions? options)
{ {
ConfigureCache(CacheNameAttribute.GetCacheName(cacheItemType), options); ConfigureCache(CacheNameAttribute.GetCacheName(cacheItemType), options);
} }
public void ConfigureCache(string cacheName, DistributedCacheEntryOptions options) public void ConfigureCache(string cacheName, DistributedCacheEntryOptions? options)
{ {
CacheConfigurators.Add(name => cacheName != name ? null : options); CacheConfigurators.Add(name => cacheName != name ? null : options);
} }

2
framework/src/Volo.Abp.Caching/Volo/Abp/Caching/CacheNameAttribute.cs

@ -33,6 +33,6 @@ public class CacheNameAttribute : Attribute
return cacheNameAttribute.Name; return cacheNameAttribute.Name;
} }
return cacheItemType.FullName.RemovePostFix("CacheItem"); return cacheItemType.FullName.RemovePostFix("CacheItem")!;
} }
} }

131
framework/src/Volo.Abp.Caching/Volo/Abp/Caching/DistributedCache.cs

@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.Extensions.Caching.Distributed; using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
@ -31,62 +30,62 @@ public class DistributedCache<TCacheItem> :
InternalCache = internalCache; InternalCache = internalCache;
} }
public TCacheItem Get(string key, bool? hideErrors = null, bool considerUow = false) public TCacheItem? Get(string key, bool? hideErrors = null, bool considerUow = false)
{ {
return InternalCache.Get(key, hideErrors, considerUow); return InternalCache.Get(key, hideErrors, considerUow);
} }
public KeyValuePair<string, TCacheItem>[] GetMany(IEnumerable<string> keys, bool? hideErrors = null, bool considerUow = false) public KeyValuePair<string, TCacheItem?>[] GetMany(IEnumerable<string> keys, bool? hideErrors = null, bool considerUow = false)
{ {
return InternalCache.GetMany(keys, hideErrors, considerUow); return InternalCache.GetMany(keys, hideErrors, considerUow);
} }
public Task<KeyValuePair<string, TCacheItem>[]> GetManyAsync(IEnumerable<string> keys, bool? hideErrors = null, bool considerUow = false, CancellationToken token = default) public Task<KeyValuePair<string, TCacheItem?>[]> GetManyAsync(IEnumerable<string> keys, bool? hideErrors = null, bool considerUow = false, CancellationToken token = default)
{ {
return InternalCache.GetManyAsync(keys, hideErrors, considerUow, token); return InternalCache.GetManyAsync(keys, hideErrors, considerUow, token);
} }
public Task<TCacheItem> GetAsync(string key, bool? hideErrors = null, bool considerUow = false, CancellationToken token = default) public Task<TCacheItem?> GetAsync(string key, bool? hideErrors = null, bool considerUow = false, CancellationToken token = default)
{ {
return InternalCache.GetAsync(key, hideErrors, considerUow, token); return InternalCache.GetAsync(key, hideErrors, considerUow, token);
} }
public TCacheItem GetOrAdd(string key, Func<TCacheItem> factory, Func<DistributedCacheEntryOptions> optionsFactory = null, bool? hideErrors = null, bool considerUow = false) public TCacheItem? GetOrAdd(string key, Func<TCacheItem> factory, Func<DistributedCacheEntryOptions>? optionsFactory = null, bool? hideErrors = null, bool considerUow = false)
{ {
return InternalCache.GetOrAdd(key, factory, optionsFactory, hideErrors, considerUow); return InternalCache.GetOrAdd(key, factory, optionsFactory, hideErrors, considerUow);
} }
public Task<TCacheItem> GetOrAddAsync(string key, Func<Task<TCacheItem>> factory, Func<DistributedCacheEntryOptions> optionsFactory = null, bool? hideErrors = null, bool considerUow = false, CancellationToken token = default) public Task<TCacheItem?> GetOrAddAsync(string key, Func<Task<TCacheItem>> factory, Func<DistributedCacheEntryOptions>? optionsFactory = null, bool? hideErrors = null, bool considerUow = false, CancellationToken token = default)
{ {
return InternalCache.GetOrAddAsync(key, factory, optionsFactory, hideErrors, considerUow, token); return InternalCache.GetOrAddAsync(key, factory, optionsFactory, hideErrors, considerUow, token);
} }
public KeyValuePair<string, TCacheItem>[] GetOrAddMany(IEnumerable<string> keys, Func<IEnumerable<string>, List<KeyValuePair<string, TCacheItem>>> factory, Func<DistributedCacheEntryOptions> optionsFactory = null, bool? hideErrors = null, bool considerUow = false) public KeyValuePair<string, TCacheItem?>[] GetOrAddMany(IEnumerable<string> keys, Func<IEnumerable<string>, List<KeyValuePair<string, TCacheItem>>> factory, Func<DistributedCacheEntryOptions>? optionsFactory = null, bool? hideErrors = null, bool considerUow = false)
{ {
return InternalCache.GetOrAddMany(keys, factory, optionsFactory, hideErrors, considerUow); return InternalCache.GetOrAddMany(keys, factory, optionsFactory, hideErrors, considerUow);
} }
public Task<KeyValuePair<string, TCacheItem>[]> GetOrAddManyAsync(IEnumerable<string> keys, Func<IEnumerable<string>, Task<List<KeyValuePair<string, TCacheItem>>>> factory, Func<DistributedCacheEntryOptions> optionsFactory = null, bool? hideErrors = null, bool considerUow = false, CancellationToken token = default) public Task<KeyValuePair<string, TCacheItem?>[]> GetOrAddManyAsync(IEnumerable<string> keys, Func<IEnumerable<string>, Task<List<KeyValuePair<string, TCacheItem>>>> factory, Func<DistributedCacheEntryOptions>? optionsFactory = null, bool? hideErrors = null, bool considerUow = false, CancellationToken token = default)
{ {
return InternalCache.GetOrAddManyAsync(keys, factory, optionsFactory, hideErrors, considerUow, token); return InternalCache.GetOrAddManyAsync(keys, factory, optionsFactory, hideErrors, considerUow, token);
} }
public void Set(string key, TCacheItem value, DistributedCacheEntryOptions options = null, bool? hideErrors = null, bool considerUow = false) public void Set(string key, TCacheItem value, DistributedCacheEntryOptions? options = null, bool? hideErrors = null, bool considerUow = false)
{ {
InternalCache.Set(key, value, options, hideErrors, considerUow); InternalCache.Set(key, value, options, hideErrors, considerUow);
} }
public Task SetAsync(string key, TCacheItem value, DistributedCacheEntryOptions options = null, bool? hideErrors = null, bool considerUow = false, CancellationToken token = default) public Task SetAsync(string key, TCacheItem value, DistributedCacheEntryOptions? options = null, bool? hideErrors = null, bool considerUow = false, CancellationToken token = default)
{ {
return InternalCache.SetAsync(key, value, options, hideErrors, considerUow, token); return InternalCache.SetAsync(key, value, options, hideErrors, considerUow, token);
} }
public void SetMany(IEnumerable<KeyValuePair<string, TCacheItem>> items, DistributedCacheEntryOptions options = null, bool? hideErrors = null, bool considerUow = false) public void SetMany(IEnumerable<KeyValuePair<string, TCacheItem>> items, DistributedCacheEntryOptions? options = null, bool? hideErrors = null, bool considerUow = false)
{ {
InternalCache.SetMany(items, options, hideErrors, considerUow); InternalCache.SetMany(items, options, hideErrors, considerUow);
} }
public Task SetManyAsync(IEnumerable<KeyValuePair<string, TCacheItem>> items, DistributedCacheEntryOptions options = null, bool? hideErrors = null, bool considerUow = false, CancellationToken token = default) public Task SetManyAsync(IEnumerable<KeyValuePair<string, TCacheItem>> items, DistributedCacheEntryOptions? options = null, bool? hideErrors = null, bool considerUow = false, CancellationToken token = default)
{ {
return InternalCache.SetManyAsync(items, options, hideErrors, considerUow, token); return InternalCache.SetManyAsync(items, options, hideErrors, considerUow, token);
} }
@ -141,12 +140,13 @@ public class DistributedCache<TCacheItem> :
/// <typeparam name="TCacheKey">The type of cache key being used.</typeparam> /// <typeparam name="TCacheKey">The type of cache key being used.</typeparam>
public class DistributedCache<TCacheItem, TCacheKey> : IDistributedCache<TCacheItem, TCacheKey> public class DistributedCache<TCacheItem, TCacheKey> : IDistributedCache<TCacheItem, TCacheKey>
where TCacheItem : class where TCacheItem : class
where TCacheKey : notnull
{ {
public const string UowCacheName = "AbpDistributedCache"; public const string UowCacheName = "AbpDistributedCache";
public ILogger<DistributedCache<TCacheItem, TCacheKey>> Logger { get; set; } public ILogger<DistributedCache<TCacheItem, TCacheKey>> Logger { get; set; }
protected string CacheName { get; set; } protected string CacheName { get; set; } = default!;
protected bool IgnoreMultiTenancy { get; set; } protected bool IgnoreMultiTenancy { get; set; }
@ -164,7 +164,7 @@ public class DistributedCache<TCacheItem, TCacheKey> : IDistributedCache<TCacheI
protected SemaphoreSlim SyncSemaphore { get; } protected SemaphoreSlim SyncSemaphore { get; }
protected DistributedCacheEntryOptions DefaultCacheOptions; protected DistributedCacheEntryOptions DefaultCacheOptions = default!;
private readonly AbpDistributedCacheOptions _distributedCacheOption; private readonly AbpDistributedCacheOptions _distributedCacheOption;
@ -195,7 +195,7 @@ public class DistributedCache<TCacheItem, TCacheKey> : IDistributedCache<TCacheI
{ {
return KeyNormalizer.NormalizeKey( return KeyNormalizer.NormalizeKey(
new DistributedCacheKeyNormalizeArgs( new DistributedCacheKeyNormalizeArgs(
key.ToString(), key.ToString()!,
CacheName, CacheName,
IgnoreMultiTenancy IgnoreMultiTenancy
) )
@ -234,7 +234,7 @@ public class DistributedCache<TCacheItem, TCacheKey> : IDistributedCache<TCacheI
/// <param name="hideErrors">Indicates to throw or hide the exceptions for the distributed cache.</param> /// <param name="hideErrors">Indicates to throw or hide the exceptions for the distributed cache.</param>
/// <param name="considerUow">This will store the cache in the current unit of work until the end of the current unit of work does not really affect the cache.</param> /// <param name="considerUow">This will store the cache in the current unit of work until the end of the current unit of work does not really affect the cache.</param>
/// <returns>The cache item, or null.</returns> /// <returns>The cache item, or null.</returns>
public virtual TCacheItem Get( public virtual TCacheItem? Get(
TCacheKey key, TCacheKey key,
bool? hideErrors = null, bool? hideErrors = null,
bool considerUow = false) bool considerUow = false)
@ -250,7 +250,7 @@ public class DistributedCache<TCacheItem, TCacheKey> : IDistributedCache<TCacheI
} }
} }
byte[] cachedBytes; byte[]? cachedBytes;
try try
{ {
@ -270,7 +270,7 @@ public class DistributedCache<TCacheItem, TCacheKey> : IDistributedCache<TCacheI
return ToCacheItem(cachedBytes); return ToCacheItem(cachedBytes);
} }
public virtual KeyValuePair<TCacheKey, TCacheItem>[] GetMany( public virtual KeyValuePair<TCacheKey, TCacheItem?>[] GetMany(
IEnumerable<TCacheKey> keys, IEnumerable<TCacheKey> keys,
bool? hideErrors = null, bool? hideErrors = null,
bool considerUow = false) bool considerUow = false)
@ -288,7 +288,7 @@ public class DistributedCache<TCacheItem, TCacheKey> : IDistributedCache<TCacheI
} }
var notCachedKeys = new List<TCacheKey>(); var notCachedKeys = new List<TCacheKey>();
var cachedValues = new List<KeyValuePair<TCacheKey, TCacheItem>>(); var cachedValues = new List<KeyValuePair<TCacheKey, TCacheItem?>>();
if (ShouldConsiderUow(considerUow)) if (ShouldConsiderUow(considerUow))
{ {
var uowCache = GetUnitOfWorkCache(); var uowCache = GetUnitOfWorkCache();
@ -297,7 +297,7 @@ public class DistributedCache<TCacheItem, TCacheKey> : IDistributedCache<TCacheI
var value = uowCache.GetOrDefault(key)?.GetUnRemovedValueOrNull(); var value = uowCache.GetOrDefault(key)?.GetUnRemovedValueOrNull();
if (value != null) if (value != null)
{ {
cachedValues.Add(new KeyValuePair<TCacheKey, TCacheItem>(key, value)); cachedValues.Add(new KeyValuePair<TCacheKey, TCacheItem?>(key, value));
} }
} }
@ -309,7 +309,7 @@ public class DistributedCache<TCacheItem, TCacheKey> : IDistributedCache<TCacheI
} }
hideErrors = hideErrors ?? _distributedCacheOption.HideErrors; hideErrors = hideErrors ?? _distributedCacheOption.HideErrors;
byte[][] cachedBytes; byte[]?[] cachedBytes;
var readKeys = notCachedKeys.Any() ? notCachedKeys.ToArray() : keyArray; var readKeys = notCachedKeys.Any() ? notCachedKeys.ToArray() : keyArray;
try try
@ -330,7 +330,7 @@ public class DistributedCache<TCacheItem, TCacheKey> : IDistributedCache<TCacheI
return cachedValues.Concat(ToCacheItems(cachedBytes, readKeys)).ToArray(); return cachedValues.Concat(ToCacheItems(cachedBytes, readKeys)).ToArray();
} }
protected virtual KeyValuePair<TCacheKey, TCacheItem>[] GetManyFallback( protected virtual KeyValuePair<TCacheKey, TCacheItem?>[] GetManyFallback(
TCacheKey[] keys, TCacheKey[] keys,
bool? hideErrors = null, bool? hideErrors = null,
bool considerUow = false) bool considerUow = false)
@ -340,7 +340,7 @@ public class DistributedCache<TCacheItem, TCacheKey> : IDistributedCache<TCacheI
try try
{ {
return keys return keys
.Select(key => new KeyValuePair<TCacheKey, TCacheItem>( .Select(key => new KeyValuePair<TCacheKey, TCacheItem?>(
key, key,
Get(key, false, considerUow) Get(key, false, considerUow)
) )
@ -358,7 +358,7 @@ public class DistributedCache<TCacheItem, TCacheKey> : IDistributedCache<TCacheI
} }
} }
public virtual async Task<KeyValuePair<TCacheKey, TCacheItem>[]> GetManyAsync( public virtual async Task<KeyValuePair<TCacheKey, TCacheItem?>[]> GetManyAsync(
IEnumerable<TCacheKey> keys, IEnumerable<TCacheKey> keys,
bool? hideErrors = null, bool? hideErrors = null,
bool considerUow = false, bool considerUow = false,
@ -378,7 +378,7 @@ public class DistributedCache<TCacheItem, TCacheKey> : IDistributedCache<TCacheI
} }
var notCachedKeys = new List<TCacheKey>(); var notCachedKeys = new List<TCacheKey>();
var cachedValues = new List<KeyValuePair<TCacheKey, TCacheItem>>(); var cachedValues = new List<KeyValuePair<TCacheKey, TCacheItem?>>();
if (ShouldConsiderUow(considerUow)) if (ShouldConsiderUow(considerUow))
{ {
var uowCache = GetUnitOfWorkCache(); var uowCache = GetUnitOfWorkCache();
@ -387,7 +387,7 @@ public class DistributedCache<TCacheItem, TCacheKey> : IDistributedCache<TCacheI
var value = uowCache.GetOrDefault(key)?.GetUnRemovedValueOrNull(); var value = uowCache.GetOrDefault(key)?.GetUnRemovedValueOrNull();
if (value != null) if (value != null)
{ {
cachedValues.Add(new KeyValuePair<TCacheKey, TCacheItem>(key, value)); cachedValues.Add(new KeyValuePair<TCacheKey, TCacheItem?>(key, value));
} }
} }
@ -399,7 +399,7 @@ public class DistributedCache<TCacheItem, TCacheKey> : IDistributedCache<TCacheI
} }
hideErrors = hideErrors ?? _distributedCacheOption.HideErrors; hideErrors = hideErrors ?? _distributedCacheOption.HideErrors;
byte[][] cachedBytes; byte[]?[] cachedBytes;
var readKeys = notCachedKeys.Any() ? notCachedKeys.ToArray() : keyArray; var readKeys = notCachedKeys.Any() ? notCachedKeys.ToArray() : keyArray;
@ -424,7 +424,7 @@ public class DistributedCache<TCacheItem, TCacheKey> : IDistributedCache<TCacheI
return cachedValues.Concat(ToCacheItems(cachedBytes, readKeys)).ToArray(); return cachedValues.Concat(ToCacheItems(cachedBytes, readKeys)).ToArray();
} }
protected virtual async Task<KeyValuePair<TCacheKey, TCacheItem>[]> GetManyFallbackAsync( protected virtual async Task<KeyValuePair<TCacheKey, TCacheItem?>[]> GetManyFallbackAsync(
TCacheKey[] keys, TCacheKey[] keys,
bool? hideErrors = null, bool? hideErrors = null,
bool considerUow = false, bool considerUow = false,
@ -434,11 +434,11 @@ public class DistributedCache<TCacheItem, TCacheKey> : IDistributedCache<TCacheI
try try
{ {
var result = new List<KeyValuePair<TCacheKey, TCacheItem>>(); var result = new List<KeyValuePair<TCacheKey, TCacheItem?>>();
foreach (var key in keys) foreach (var key in keys)
{ {
result.Add(new KeyValuePair<TCacheKey, TCacheItem>( result.Add(new KeyValuePair<TCacheKey, TCacheItem?>(
key, key,
await GetAsync(key, false, considerUow, token: token)) await GetAsync(key, false, considerUow, token: token))
); );
@ -466,7 +466,7 @@ public class DistributedCache<TCacheItem, TCacheKey> : IDistributedCache<TCacheI
/// <param name="considerUow">This will store the cache in the current unit of work until the end of the current unit of work does not really affect the cache.</param> /// <param name="considerUow">This will store the cache in the current unit of work until the end of the current unit of work does not really affect the cache.</param>
/// <param name="token">The <see cref="T:System.Threading.CancellationToken" /> for the task.</param> /// <param name="token">The <see cref="T:System.Threading.CancellationToken" /> for the task.</param>
/// <returns>The cache item, or null.</returns> /// <returns>The cache item, or null.</returns>
public virtual async Task<TCacheItem> GetAsync( public virtual async Task<TCacheItem?> GetAsync(
TCacheKey key, TCacheKey key,
bool? hideErrors = null, bool? hideErrors = null,
bool considerUow = false, bool considerUow = false,
@ -483,7 +483,7 @@ public class DistributedCache<TCacheItem, TCacheKey> : IDistributedCache<TCacheI
} }
} }
byte[] cachedBytes; byte[]? cachedBytes;
try try
{ {
@ -521,10 +521,10 @@ public class DistributedCache<TCacheItem, TCacheKey> : IDistributedCache<TCacheI
/// <param name="hideErrors">Indicates to throw or hide the exceptions for the distributed cache.</param> /// <param name="hideErrors">Indicates to throw or hide the exceptions for the distributed cache.</param>
/// <param name="considerUow">This will store the cache in the current unit of work until the end of the current unit of work does not really affect the cache.</param> /// <param name="considerUow">This will store the cache in the current unit of work until the end of the current unit of work does not really affect the cache.</param>
/// <returns>The cache item.</returns> /// <returns>The cache item.</returns>
public virtual TCacheItem GetOrAdd( public virtual TCacheItem? GetOrAdd(
TCacheKey key, TCacheKey key,
Func<TCacheItem> factory, Func<TCacheItem> factory,
Func<DistributedCacheEntryOptions> optionsFactory = null, Func<DistributedCacheEntryOptions>? optionsFactory = null,
bool? hideErrors = null, bool? hideErrors = null,
bool considerUow = false) bool considerUow = false)
{ {
@ -574,10 +574,10 @@ public class DistributedCache<TCacheItem, TCacheKey> : IDistributedCache<TCacheI
/// <param name="considerUow">This will store the cache in the current unit of work until the end of the current unit of work does not really affect the cache.</param> /// <param name="considerUow">This will store the cache in the current unit of work until the end of the current unit of work does not really affect the cache.</param>
/// <param name="token">The <see cref="T:System.Threading.CancellationToken" /> for the task.</param> /// <param name="token">The <see cref="T:System.Threading.CancellationToken" /> for the task.</param>
/// <returns>The cache item.</returns> /// <returns>The cache item.</returns>
public virtual async Task<TCacheItem> GetOrAddAsync( public virtual async Task<TCacheItem?> GetOrAddAsync(
TCacheKey key, TCacheKey key,
Func<Task<TCacheItem>> factory, Func<Task<TCacheItem>> factory,
Func<DistributedCacheEntryOptions> optionsFactory = null, Func<DistributedCacheEntryOptions>? optionsFactory = null,
bool? hideErrors = null, bool? hideErrors = null,
bool considerUow = false, bool considerUow = false,
CancellationToken token = default) CancellationToken token = default)
@ -618,15 +618,15 @@ public class DistributedCache<TCacheItem, TCacheKey> : IDistributedCache<TCacheI
return value; return value;
} }
public KeyValuePair<TCacheKey, TCacheItem>[] GetOrAddMany( public KeyValuePair<TCacheKey, TCacheItem?>[] GetOrAddMany(
IEnumerable<TCacheKey> keys, IEnumerable<TCacheKey> keys,
Func<IEnumerable<TCacheKey>, List<KeyValuePair<TCacheKey, TCacheItem>>> factory, Func<IEnumerable<TCacheKey>, List<KeyValuePair<TCacheKey, TCacheItem>>> factory,
Func<DistributedCacheEntryOptions> optionsFactory = null, Func<DistributedCacheEntryOptions>? optionsFactory = null,
bool? hideErrors = null, bool? hideErrors = null,
bool considerUow = false) bool considerUow = false)
{ {
KeyValuePair<TCacheKey, TCacheItem>[] result; KeyValuePair<TCacheKey, TCacheItem?>[] result;
var keyArray = keys.ToArray(); var keyArray = keys.ToArray();
var cacheSupportsMultipleItems = Cache as ICacheSupportsMultipleItems; var cacheSupportsMultipleItems = Cache as ICacheSupportsMultipleItems;
@ -641,7 +641,7 @@ public class DistributedCache<TCacheItem, TCacheKey> : IDistributedCache<TCacheI
else else
{ {
var notCachedKeys = new List<TCacheKey>(); var notCachedKeys = new List<TCacheKey>();
var cachedValues = new List<KeyValuePair<TCacheKey, TCacheItem>>(); var cachedValues = new List<KeyValuePair<TCacheKey, TCacheItem?>>();
if (ShouldConsiderUow(considerUow)) if (ShouldConsiderUow(considerUow))
{ {
var uowCache = GetUnitOfWorkCache(); var uowCache = GetUnitOfWorkCache();
@ -650,7 +650,7 @@ public class DistributedCache<TCacheItem, TCacheKey> : IDistributedCache<TCacheI
var value = uowCache.GetOrDefault(key)?.GetUnRemovedValueOrNull(); var value = uowCache.GetOrDefault(key)?.GetUnRemovedValueOrNull();
if (value != null) if (value != null)
{ {
cachedValues.Add(new KeyValuePair<TCacheKey, TCacheItem>(key, value)); cachedValues.Add(new KeyValuePair<TCacheKey, TCacheItem?>(key, value));
} }
} }
@ -662,7 +662,7 @@ public class DistributedCache<TCacheItem, TCacheKey> : IDistributedCache<TCacheI
} }
hideErrors = hideErrors ?? _distributedCacheOption.HideErrors; hideErrors = hideErrors ?? _distributedCacheOption.HideErrors;
byte[][] cachedBytes; byte[]?[] cachedBytes;
var readKeys = notCachedKeys.Any() ? notCachedKeys.ToArray() : keyArray; var readKeys = notCachedKeys.Any() ? notCachedKeys.ToArray() : keyArray;
try try
@ -685,7 +685,7 @@ public class DistributedCache<TCacheItem, TCacheKey> : IDistributedCache<TCacheI
if (result.All(x => x.Value != null)) if (result.All(x => x.Value != null))
{ {
return result; return result!;
} }
var missingKeys = new List<TCacheKey>(); var missingKeys = new List<TCacheKey>();
@ -708,22 +708,22 @@ public class DistributedCache<TCacheItem, TCacheKey> : IDistributedCache<TCacheI
foreach (var index in missingValuesIndex) foreach (var index in missingValuesIndex)
{ {
result[index] = valueQueue.Dequeue(); result[index] = valueQueue.Dequeue()!;
} }
return result; return result;
} }
public async Task<KeyValuePair<TCacheKey, TCacheItem>[]> GetOrAddManyAsync( public async Task<KeyValuePair<TCacheKey, TCacheItem?>[]> GetOrAddManyAsync(
IEnumerable<TCacheKey> keys, IEnumerable<TCacheKey> keys,
Func<IEnumerable<TCacheKey>, Task<List<KeyValuePair<TCacheKey, TCacheItem>>>> factory, Func<IEnumerable<TCacheKey>, Task<List<KeyValuePair<TCacheKey, TCacheItem>>>> factory,
Func<DistributedCacheEntryOptions> optionsFactory = null, Func<DistributedCacheEntryOptions>? optionsFactory = null,
bool? hideErrors = null, bool? hideErrors = null,
bool considerUow = false, bool considerUow = false,
CancellationToken token = default) CancellationToken token = default)
{ {
KeyValuePair<TCacheKey, TCacheItem>[] result; KeyValuePair<TCacheKey, TCacheItem?>[] result;
var keyArray = keys.ToArray(); var keyArray = keys.ToArray();
var cacheSupportsMultipleItems = Cache as ICacheSupportsMultipleItems; var cacheSupportsMultipleItems = Cache as ICacheSupportsMultipleItems;
@ -737,7 +737,7 @@ public class DistributedCache<TCacheItem, TCacheKey> : IDistributedCache<TCacheI
else else
{ {
var notCachedKeys = new List<TCacheKey>(); var notCachedKeys = new List<TCacheKey>();
var cachedValues = new List<KeyValuePair<TCacheKey, TCacheItem>>(); var cachedValues = new List<KeyValuePair<TCacheKey, TCacheItem?>>();
if (ShouldConsiderUow(considerUow)) if (ShouldConsiderUow(considerUow))
{ {
var uowCache = GetUnitOfWorkCache(); var uowCache = GetUnitOfWorkCache();
@ -746,7 +746,7 @@ public class DistributedCache<TCacheItem, TCacheKey> : IDistributedCache<TCacheI
var value = uowCache.GetOrDefault(key)?.GetUnRemovedValueOrNull(); var value = uowCache.GetOrDefault(key)?.GetUnRemovedValueOrNull();
if (value != null) if (value != null)
{ {
cachedValues.Add(new KeyValuePair<TCacheKey, TCacheItem>(key, value)); cachedValues.Add(new KeyValuePair<TCacheKey, TCacheItem?>(key, value));
} }
} }
@ -758,7 +758,7 @@ public class DistributedCache<TCacheItem, TCacheKey> : IDistributedCache<TCacheI
} }
hideErrors = hideErrors ?? _distributedCacheOption.HideErrors; hideErrors = hideErrors ?? _distributedCacheOption.HideErrors;
byte[][] cachedBytes; byte[]?[] cachedBytes;
var readKeys = notCachedKeys.Any() ? notCachedKeys.ToArray() : keyArray; var readKeys = notCachedKeys.Any() ? notCachedKeys.ToArray() : keyArray;
try try
@ -804,7 +804,7 @@ public class DistributedCache<TCacheItem, TCacheKey> : IDistributedCache<TCacheI
foreach (var index in missingValuesIndex) foreach (var index in missingValuesIndex)
{ {
result[index] = valueQueue.Dequeue(); result[index] = valueQueue.Dequeue()!;
} }
return result; return result;
@ -821,7 +821,7 @@ public class DistributedCache<TCacheItem, TCacheKey> : IDistributedCache<TCacheI
public virtual void Set( public virtual void Set(
TCacheKey key, TCacheKey key,
TCacheItem value, TCacheItem value,
DistributedCacheEntryOptions options = null, DistributedCacheEntryOptions? options = null,
bool? hideErrors = null, bool? hideErrors = null,
bool considerUow = false) bool considerUow = false)
{ {
@ -886,7 +886,7 @@ public class DistributedCache<TCacheItem, TCacheKey> : IDistributedCache<TCacheI
public virtual async Task SetAsync( public virtual async Task SetAsync(
TCacheKey key, TCacheKey key,
TCacheItem value, TCacheItem value,
DistributedCacheEntryOptions options = null, DistributedCacheEntryOptions? options = null,
bool? hideErrors = null, bool? hideErrors = null,
bool considerUow = false, bool considerUow = false,
CancellationToken token = default) CancellationToken token = default)
@ -939,7 +939,7 @@ public class DistributedCache<TCacheItem, TCacheKey> : IDistributedCache<TCacheI
public void SetMany( public void SetMany(
IEnumerable<KeyValuePair<TCacheKey, TCacheItem>> items, IEnumerable<KeyValuePair<TCacheKey, TCacheItem>> items,
DistributedCacheEntryOptions options = null, DistributedCacheEntryOptions? options = null,
bool? hideErrors = null, bool? hideErrors = null,
bool considerUow = false) bool considerUow = false)
{ {
@ -1012,7 +1012,7 @@ public class DistributedCache<TCacheItem, TCacheKey> : IDistributedCache<TCacheI
protected virtual void SetManyFallback( protected virtual void SetManyFallback(
KeyValuePair<TCacheKey, TCacheItem>[] items, KeyValuePair<TCacheKey, TCacheItem>[] items,
DistributedCacheEntryOptions options = null, DistributedCacheEntryOptions? options = null,
bool? hideErrors = null, bool? hideErrors = null,
bool considerUow = false) bool considerUow = false)
{ {
@ -1045,7 +1045,7 @@ public class DistributedCache<TCacheItem, TCacheKey> : IDistributedCache<TCacheI
public virtual async Task SetManyAsync( public virtual async Task SetManyAsync(
IEnumerable<KeyValuePair<TCacheKey, TCacheItem>> items, IEnumerable<KeyValuePair<TCacheKey, TCacheItem>> items,
DistributedCacheEntryOptions options = null, DistributedCacheEntryOptions? options = null,
bool? hideErrors = null, bool? hideErrors = null,
bool considerUow = false, bool considerUow = false,
CancellationToken token = default) CancellationToken token = default)
@ -1117,7 +1117,7 @@ public class DistributedCache<TCacheItem, TCacheKey> : IDistributedCache<TCacheI
protected virtual async Task SetManyFallbackAsync( protected virtual async Task SetManyFallbackAsync(
KeyValuePair<TCacheKey, TCacheItem>[] items, KeyValuePair<TCacheKey, TCacheItem>[] items,
DistributedCacheEntryOptions options = null, DistributedCacheEntryOptions? options = null,
bool? hideErrors = null, bool? hideErrors = null,
bool considerUow = false, bool considerUow = false,
CancellationToken token = default) CancellationToken token = default)
@ -1516,19 +1516,19 @@ public class DistributedCache<TCacheItem, TCacheKey> : IDistributedCache<TCacheI
} }
} }
protected virtual KeyValuePair<TCacheKey, TCacheItem>[] ToCacheItems(byte[][] itemBytes, TCacheKey[] itemKeys) protected virtual KeyValuePair<TCacheKey, TCacheItem?>[] ToCacheItems(byte[]?[] itemBytes, TCacheKey[] itemKeys)
{ {
if (itemBytes.Length != itemKeys.Length) if (itemBytes.Length != itemKeys.Length)
{ {
throw new AbpException("count of the item bytes should be same with the count of the given keys"); throw new AbpException("count of the item bytes should be same with the count of the given keys");
} }
var result = new List<KeyValuePair<TCacheKey, TCacheItem>>(); var result = new List<KeyValuePair<TCacheKey, TCacheItem?>>();
for (int i = 0; i < itemKeys.Length; i++) for (var i = 0; i < itemKeys.Length; i++)
{ {
result.Add( result.Add(
new KeyValuePair<TCacheKey, TCacheItem>( new KeyValuePair<TCacheKey, TCacheItem?>(
itemKeys[i], itemKeys[i],
ToCacheItem(itemBytes[i]) ToCacheItem(itemBytes[i])
) )
@ -1538,8 +1538,7 @@ public class DistributedCache<TCacheItem, TCacheKey> : IDistributedCache<TCacheI
return result.ToArray(); return result.ToArray();
} }
[CanBeNull] protected virtual TCacheItem? ToCacheItem(byte[]? bytes)
protected virtual TCacheItem ToCacheItem([CanBeNull] byte[] bytes)
{ {
if (bytes == null) if (bytes == null)
{ {
@ -1560,10 +1559,10 @@ public class DistributedCache<TCacheItem, TCacheKey> : IDistributedCache<TCacheI
).ToArray(); ).ToArray();
} }
private static KeyValuePair<TCacheKey, TCacheItem>[] ToCacheItemsWithDefaultValues(TCacheKey[] keys) private static KeyValuePair<TCacheKey, TCacheItem?>[] ToCacheItemsWithDefaultValues(TCacheKey[] keys)
{ {
return keys return keys
.Select(key => new KeyValuePair<TCacheKey, TCacheItem>(key, default)) .Select(key => new KeyValuePair<TCacheKey, TCacheItem?>(key, default))
.ToArray(); .ToArray();
} }

4
framework/src/Volo.Abp.Caching/Volo/Abp/Caching/ICacheSupportsMultipleItems.cs

@ -7,11 +7,11 @@ namespace Volo.Abp.Caching;
public interface ICacheSupportsMultipleItems public interface ICacheSupportsMultipleItems
{ {
byte[][] GetMany( byte[]?[] GetMany(
IEnumerable<string> keys IEnumerable<string> keys
); );
Task<byte[][]> GetManyAsync( Task<byte[]?[]> GetManyAsync(
IEnumerable<string> keys, IEnumerable<string> keys,
CancellationToken token = default CancellationToken token = default
); );

32
framework/src/Volo.Abp.Caching/Volo/Abp/Caching/IDistributedCache.cs

@ -33,7 +33,7 @@ public interface IDistributedCache<TCacheItem, TCacheKey>
/// <param name="hideErrors">Indicates to throw or hide the exceptions for the distributed cache.</param> /// <param name="hideErrors">Indicates to throw or hide the exceptions for the distributed cache.</param>
/// <param name="considerUow">This will store the cache in the current unit of work until the end of the current unit of work does not really affect the cache.</param> /// <param name="considerUow">This will store the cache in the current unit of work until the end of the current unit of work does not really affect the cache.</param>
/// <returns>The cache item, or null.</returns> /// <returns>The cache item, or null.</returns>
TCacheItem Get( TCacheItem? Get(
TCacheKey key, TCacheKey key,
bool? hideErrors = null, bool? hideErrors = null,
bool considerUow = false bool considerUow = false
@ -50,7 +50,7 @@ public interface IDistributedCache<TCacheItem, TCacheKey>
/// <param name="hideErrors">Indicates to throw or hide the exceptions for the distributed cache.</param> /// <param name="hideErrors">Indicates to throw or hide the exceptions for the distributed cache.</param>
/// <param name="considerUow">This will store the cache in the current unit of work until the end of the current unit of work does not really affect the cache.</param> /// <param name="considerUow">This will store the cache in the current unit of work until the end of the current unit of work does not really affect the cache.</param>
/// <returns>List of cache items.</returns> /// <returns>List of cache items.</returns>
KeyValuePair<TCacheKey, TCacheItem>[] GetMany( KeyValuePair<TCacheKey, TCacheItem?>[] GetMany(
IEnumerable<TCacheKey> keys, IEnumerable<TCacheKey> keys,
bool? hideErrors = null, bool? hideErrors = null,
bool considerUow = false bool considerUow = false
@ -69,7 +69,7 @@ public interface IDistributedCache<TCacheItem, TCacheKey>
/// <param name="considerUow">This will store the cache in the current unit of work until the end of the current unit of work does not really affect the cache.</param> /// <param name="considerUow">This will store the cache in the current unit of work until the end of the current unit of work does not really affect the cache.</param>
/// /// <param name="token">The <see cref="T:System.Threading.CancellationToken" /> for the task.</param> /// /// <param name="token">The <see cref="T:System.Threading.CancellationToken" /> for the task.</param>
/// <returns>List of cache items.</returns> /// <returns>List of cache items.</returns>
Task<KeyValuePair<TCacheKey, TCacheItem>[]> GetManyAsync( Task<KeyValuePair<TCacheKey, TCacheItem?>[]> GetManyAsync(
IEnumerable<TCacheKey> keys, IEnumerable<TCacheKey> keys,
bool? hideErrors = null, bool? hideErrors = null,
bool considerUow = false, bool considerUow = false,
@ -84,7 +84,7 @@ public interface IDistributedCache<TCacheItem, TCacheKey>
/// <param name="considerUow">This will store the cache in the current unit of work until the end of the current unit of work does not really affect the cache.</param> /// <param name="considerUow">This will store the cache in the current unit of work until the end of the current unit of work does not really affect the cache.</param>
/// <param name="token">The <see cref="T:System.Threading.CancellationToken" /> for the task.</param> /// <param name="token">The <see cref="T:System.Threading.CancellationToken" /> for the task.</param>
/// <returns>The cache item, or null.</returns> /// <returns>The cache item, or null.</returns>
Task<TCacheItem> GetAsync( Task<TCacheItem?> GetAsync(
[NotNull] TCacheKey key, [NotNull] TCacheKey key,
bool? hideErrors = null, bool? hideErrors = null,
bool considerUow = false, bool considerUow = false,
@ -101,10 +101,10 @@ public interface IDistributedCache<TCacheItem, TCacheKey>
/// <param name="hideErrors">Indicates to throw or hide the exceptions for the distributed cache.</param> /// <param name="hideErrors">Indicates to throw or hide the exceptions for the distributed cache.</param>
/// <param name="considerUow">This will store the cache in the current unit of work until the end of the current unit of work does not really affect the cache.</param> /// <param name="considerUow">This will store the cache in the current unit of work until the end of the current unit of work does not really affect the cache.</param>
/// <returns>The cache item.</returns> /// <returns>The cache item.</returns>
TCacheItem GetOrAdd( TCacheItem? GetOrAdd(
TCacheKey key, TCacheKey key,
Func<TCacheItem> factory, Func<TCacheItem> factory,
Func<DistributedCacheEntryOptions> optionsFactory = null, Func<DistributedCacheEntryOptions>? optionsFactory = null,
bool? hideErrors = null, bool? hideErrors = null,
bool considerUow = false bool considerUow = false
); );
@ -120,10 +120,10 @@ public interface IDistributedCache<TCacheItem, TCacheKey>
/// <param name="considerUow">This will store the cache in the current unit of work until the end of the current unit of work does not really affect the cache.</param> /// <param name="considerUow">This will store the cache in the current unit of work until the end of the current unit of work does not really affect the cache.</param>
/// <param name="token">The <see cref="T:System.Threading.CancellationToken" /> for the task.</param> /// <param name="token">The <see cref="T:System.Threading.CancellationToken" /> for the task.</param>
/// <returns>The cache item.</returns> /// <returns>The cache item.</returns>
Task<TCacheItem> GetOrAddAsync( Task<TCacheItem?> GetOrAddAsync(
[NotNull] TCacheKey key, [NotNull] TCacheKey key,
Func<Task<TCacheItem>> factory, Func<Task<TCacheItem>> factory,
Func<DistributedCacheEntryOptions> optionsFactory = null, Func<DistributedCacheEntryOptions>? optionsFactory = null,
bool? hideErrors = null, bool? hideErrors = null,
bool considerUow = false, bool considerUow = false,
CancellationToken token = default CancellationToken token = default
@ -139,10 +139,10 @@ public interface IDistributedCache<TCacheItem, TCacheKey>
/// <param name="hideErrors">Indicates to throw or hide the exceptions for the distributed cache.</param> /// <param name="hideErrors">Indicates to throw or hide the exceptions for the distributed cache.</param>
/// <param name="considerUow">This will store the cache in the current unit of work until the end of the current unit of work does not really affect the cache.</param> /// <param name="considerUow">This will store the cache in the current unit of work until the end of the current unit of work does not really affect the cache.</param>
/// <returns>The cache items.</returns> /// <returns>The cache items.</returns>
KeyValuePair<TCacheKey, TCacheItem>[] GetOrAddMany( KeyValuePair<TCacheKey, TCacheItem?>[] GetOrAddMany(
IEnumerable<TCacheKey> keys, IEnumerable<TCacheKey> keys,
Func<IEnumerable<TCacheKey>, List<KeyValuePair<TCacheKey, TCacheItem>>> factory, Func<IEnumerable<TCacheKey>, List<KeyValuePair<TCacheKey, TCacheItem>>> factory,
Func<DistributedCacheEntryOptions> optionsFactory = null, Func<DistributedCacheEntryOptions>? optionsFactory = null,
bool? hideErrors = null, bool? hideErrors = null,
bool considerUow = false bool considerUow = false
); );
@ -158,10 +158,10 @@ public interface IDistributedCache<TCacheItem, TCacheKey>
/// <param name="considerUow">This will store the cache in the current unit of work until the end of the current unit of work does not really affect the cache.</param> /// <param name="considerUow">This will store the cache in the current unit of work until the end of the current unit of work does not really affect the cache.</param>
/// <param name="token">The <see cref="T:System.Threading.CancellationToken" /> for the task.</param> /// <param name="token">The <see cref="T:System.Threading.CancellationToken" /> for the task.</param>
/// <returns>The cache items.</returns> /// <returns>The cache items.</returns>
Task<KeyValuePair<TCacheKey, TCacheItem>[]> GetOrAddManyAsync( Task<KeyValuePair<TCacheKey, TCacheItem?>[]> GetOrAddManyAsync(
IEnumerable<TCacheKey> keys, IEnumerable<TCacheKey> keys,
Func<IEnumerable<TCacheKey>, Task<List<KeyValuePair<TCacheKey, TCacheItem>>>> factory, Func<IEnumerable<TCacheKey>, Task<List<KeyValuePair<TCacheKey, TCacheItem>>>> factory,
Func<DistributedCacheEntryOptions> optionsFactory = null, Func<DistributedCacheEntryOptions>? optionsFactory = null,
bool? hideErrors = null, bool? hideErrors = null,
bool considerUow = false, bool considerUow = false,
CancellationToken token = default CancellationToken token = default
@ -178,7 +178,7 @@ public interface IDistributedCache<TCacheItem, TCacheKey>
void Set( void Set(
TCacheKey key, TCacheKey key,
TCacheItem value, TCacheItem value,
DistributedCacheEntryOptions options = null, DistributedCacheEntryOptions? options = null,
bool? hideErrors = null, bool? hideErrors = null,
bool considerUow = false bool considerUow = false
); );
@ -196,7 +196,7 @@ public interface IDistributedCache<TCacheItem, TCacheKey>
Task SetAsync( Task SetAsync(
[NotNull] TCacheKey key, [NotNull] TCacheKey key,
[NotNull] TCacheItem value, [NotNull] TCacheItem value,
[CanBeNull] DistributedCacheEntryOptions options = null, DistributedCacheEntryOptions? options = null,
bool? hideErrors = null, bool? hideErrors = null,
bool considerUow = false, bool considerUow = false,
CancellationToken token = default CancellationToken token = default
@ -212,7 +212,7 @@ public interface IDistributedCache<TCacheItem, TCacheKey>
/// <param name="considerUow">This will store the cache in the current unit of work until the end of the current unit of work does not really affect the cache.</param> /// <param name="considerUow">This will store the cache in the current unit of work until the end of the current unit of work does not really affect the cache.</param>
void SetMany( void SetMany(
IEnumerable<KeyValuePair<TCacheKey, TCacheItem>> items, IEnumerable<KeyValuePair<TCacheKey, TCacheItem>> items,
DistributedCacheEntryOptions options = null, DistributedCacheEntryOptions? options = null,
bool? hideErrors = null, bool? hideErrors = null,
bool considerUow = false bool considerUow = false
); );
@ -229,7 +229,7 @@ public interface IDistributedCache<TCacheItem, TCacheKey>
/// <returns>The <see cref="T:System.Threading.Tasks.Task" /> indicating that the operation is asynchronous.</returns> /// <returns>The <see cref="T:System.Threading.Tasks.Task" /> indicating that the operation is asynchronous.</returns>
Task SetManyAsync( Task SetManyAsync(
IEnumerable<KeyValuePair<TCacheKey, TCacheItem>> items, IEnumerable<KeyValuePair<TCacheKey, TCacheItem>> items,
DistributedCacheEntryOptions options = null, DistributedCacheEntryOptions? options = null,
bool? hideErrors = null, bool? hideErrors = null,
bool considerUow = false, bool considerUow = false,
CancellationToken token = default CancellationToken token = default

2
framework/src/Volo.Abp.Caching/Volo/Abp/Caching/UnitOfWorkCacheItem.cs

@ -8,7 +8,7 @@ public class UnitOfWorkCacheItem<TValue>
{ {
public bool IsRemoved { get; set; } public bool IsRemoved { get; set; }
public TValue Value { get; set; } public TValue? Value { get; set; }
public UnitOfWorkCacheItem() public UnitOfWorkCacheItem()
{ {

2
framework/src/Volo.Abp.Caching/Volo/Abp/Caching/UnitOfWorkCacheItemExtensions.cs

@ -2,7 +2,7 @@
public static class UnitOfWorkCacheItemExtensions public static class UnitOfWorkCacheItemExtensions
{ {
public static TValue GetUnRemovedValueOrNull<TValue>(this UnitOfWorkCacheItem<TValue> item) public static TValue? GetUnRemovedValueOrNull<TValue>(this UnitOfWorkCacheItem<TValue>? item)
where TValue : class where TValue : class
{ {
return item != null && !item.IsRemoved ? item.Value : null; return item != null && !item.IsRemoved ? item.Value : null;

12
framework/src/Volo.Abp.Core/Microsoft/Extensions/Configuration/AbpConfigurationBuilderOptions.cs

@ -8,13 +8,13 @@ public class AbpConfigurationBuilderOptions
/// Used to set assembly which is used to get the user secret id for the application. /// Used to set assembly which is used to get the user secret id for the application.
/// Use this or <see cref="UserSecretsId"/> (higher priority) /// Use this or <see cref="UserSecretsId"/> (higher priority)
/// </summary> /// </summary>
public Assembly UserSecretsAssembly { get; set; } public Assembly? UserSecretsAssembly { get; set; }
/// <summary> /// <summary>
/// Used to set user secret id for the application. /// Used to set user secret id for the application.
/// Use this (higher priority) or <see cref="UserSecretsAssembly"/> /// Use this (higher priority) or <see cref="UserSecretsAssembly"/>
/// </summary> /// </summary>
public string UserSecretsId { get; set; } public string? UserSecretsId { get; set; }
/// <summary> /// <summary>
/// Default value: "appsettings". /// Default value: "appsettings".
@ -34,20 +34,20 @@ public class AbpConfigurationBuilderOptions
/// <summary> /// <summary>
/// Environment name. Generally used "Development", "Staging" or "Production". /// Environment name. Generally used "Development", "Staging" or "Production".
/// </summary> /// </summary>
public string EnvironmentName { get; set; } public string? EnvironmentName { get; set; }
/// <summary> /// <summary>
/// Base path to read the configuration file indicated by <see cref="FileName"/>. /// Base path to read the configuration file indicated by <see cref="FileName"/>.
/// </summary> /// </summary>
public string BasePath { get; set; } public string? BasePath { get; set; }
/// <summary> /// <summary>
/// Prefix for the environment variables. /// Prefix for the environment variables.
/// </summary> /// </summary>
public string EnvironmentVariablesPrefix { get; set; } public string? EnvironmentVariablesPrefix { get; set; }
/// <summary> /// <summary>
/// Command line arguments. /// Command line arguments.
/// </summary> /// </summary>
public string[] CommandLineArgs { get; set; } public string[]? CommandLineArgs { get; set; }
} }

6
framework/src/Volo.Abp.Core/Microsoft/Extensions/Configuration/ConfigurationHelper.cs

@ -6,8 +6,8 @@ namespace Microsoft.Extensions.Configuration;
public static class ConfigurationHelper public static class ConfigurationHelper
{ {
public static IConfigurationRoot BuildConfiguration( public static IConfigurationRoot BuildConfiguration(
AbpConfigurationBuilderOptions options = null, AbpConfigurationBuilderOptions? options = null,
Action<IConfigurationBuilder> builderAction = null) Action<IConfigurationBuilder>? builderAction = null)
{ {
options ??= new AbpConfigurationBuilderOptions(); options ??= new AbpConfigurationBuilderOptions();
@ -17,7 +17,7 @@ public static class ConfigurationHelper
} }
var builder = new ConfigurationBuilder() var builder = new ConfigurationBuilder()
.SetBasePath(options.BasePath) .SetBasePath(options.BasePath!)
.AddJsonFile(options.FileName + ".json", optional: options.Optional, reloadOnChange: options.ReloadOnChange); .AddJsonFile(options.FileName + ".json", optional: options.Optional, reloadOnChange: options.ReloadOnChange);
if (!options.EnvironmentName.IsNullOrEmpty()) if (!options.EnvironmentName.IsNullOrEmpty())

11
framework/src/Volo.Abp.Core/Microsoft/Extensions/DependencyInjection/ServiceCollectionApplicationExtensions.cs

@ -10,7 +10,7 @@ public static class ServiceCollectionApplicationExtensions
{ {
public static IAbpApplicationWithExternalServiceProvider AddApplication<TStartupModule>( public static IAbpApplicationWithExternalServiceProvider AddApplication<TStartupModule>(
[NotNull] this IServiceCollection services, [NotNull] this IServiceCollection services,
[CanBeNull] Action<AbpApplicationCreationOptions> optionsAction = null) Action<AbpApplicationCreationOptions>? optionsAction = null)
where TStartupModule : IAbpModule where TStartupModule : IAbpModule
{ {
return AbpApplicationFactory.Create<TStartupModule>(services, optionsAction); return AbpApplicationFactory.Create<TStartupModule>(services, optionsAction);
@ -19,14 +19,14 @@ public static class ServiceCollectionApplicationExtensions
public static IAbpApplicationWithExternalServiceProvider AddApplication( public static IAbpApplicationWithExternalServiceProvider AddApplication(
[NotNull] this IServiceCollection services, [NotNull] this IServiceCollection services,
[NotNull] Type startupModuleType, [NotNull] Type startupModuleType,
[CanBeNull] Action<AbpApplicationCreationOptions> optionsAction = null) Action<AbpApplicationCreationOptions>? optionsAction = null)
{ {
return AbpApplicationFactory.Create(startupModuleType, services, optionsAction); return AbpApplicationFactory.Create(startupModuleType, services, optionsAction);
} }
public async static Task<IAbpApplicationWithExternalServiceProvider> AddApplicationAsync<TStartupModule>( public async static Task<IAbpApplicationWithExternalServiceProvider> AddApplicationAsync<TStartupModule>(
[NotNull] this IServiceCollection services, [NotNull] this IServiceCollection services,
[CanBeNull] Action<AbpApplicationCreationOptions> optionsAction = null) Action<AbpApplicationCreationOptions>? optionsAction = null)
where TStartupModule : IAbpModule where TStartupModule : IAbpModule
{ {
return await AbpApplicationFactory.CreateAsync<TStartupModule>(services, optionsAction); return await AbpApplicationFactory.CreateAsync<TStartupModule>(services, optionsAction);
@ -35,13 +35,12 @@ public static class ServiceCollectionApplicationExtensions
public async static Task<IAbpApplicationWithExternalServiceProvider> AddApplicationAsync( public async static Task<IAbpApplicationWithExternalServiceProvider> AddApplicationAsync(
[NotNull] this IServiceCollection services, [NotNull] this IServiceCollection services,
[NotNull] Type startupModuleType, [NotNull] Type startupModuleType,
[CanBeNull] Action<AbpApplicationCreationOptions> optionsAction = null) Action<AbpApplicationCreationOptions>? optionsAction = null)
{ {
return await AbpApplicationFactory.CreateAsync(startupModuleType, services, optionsAction); return await AbpApplicationFactory.CreateAsync(startupModuleType, services, optionsAction);
} }
[CanBeNull] public static string? GetApplicationName(this IServiceCollection services)
public static string GetApplicationName(this IServiceCollection services)
{ {
return services.GetSingletonInstance<IApplicationInfoAccessor>().ApplicationName; return services.GetSingletonInstance<IApplicationInfoAccessor>().ApplicationName;
} }

26
framework/src/Volo.Abp.Core/Microsoft/Extensions/DependencyInjection/ServiceCollectionCommonExtensions.cs

@ -24,9 +24,9 @@ public static class ServiceCollectionCommonExtensions
return services.GetSingletonInstance<ITypeFinder>(); return services.GetSingletonInstance<ITypeFinder>();
} }
public static T GetSingletonInstanceOrNull<T>(this IServiceCollection services) public static T? GetSingletonInstanceOrNull<T>(this IServiceCollection services)
{ {
return (T)services return (T?)services
.FirstOrDefault(d => d.ServiceType == typeof(T)) .FirstOrDefault(d => d.ServiceType == typeof(T))
?.ImplementationInstance; ?.ImplementationInstance;
} }
@ -65,13 +65,13 @@ public static class ServiceCollectionCommonExtensions
.GetMethods() .GetMethods()
.Single(m => m.Name == nameof(BuildServiceProviderFromFactory) && m.IsGenericMethod) .Single(m => m.Name == nameof(BuildServiceProviderFromFactory) && m.IsGenericMethod)
.MakeGenericMethod(containerBuilderType) .MakeGenericMethod(containerBuilderType)
.Invoke(null, new object[] { services, null }); .Invoke(null, new object?[] { services, null })!;
} }
return services.BuildServiceProvider(); return services.BuildServiceProvider();
} }
public static IServiceProvider BuildServiceProviderFromFactory<TContainerBuilder>([NotNull] this IServiceCollection services, Action<TContainerBuilder> builderAction = null) public static IServiceProvider BuildServiceProviderFromFactory<TContainerBuilder>([NotNull] this IServiceCollection services, Action<TContainerBuilder>? builderAction = null) where TContainerBuilder : notnull
{ {
Check.NotNull(services, nameof(services)); Check.NotNull(services, nameof(services));
@ -90,7 +90,7 @@ public static class ServiceCollectionCommonExtensions
/// Resolves a dependency using given <see cref="IServiceCollection"/>. /// Resolves a dependency using given <see cref="IServiceCollection"/>.
/// This method should be used only after dependency injection registration phase completed. /// This method should be used only after dependency injection registration phase completed.
/// </summary> /// </summary>
internal static T GetService<T>(this IServiceCollection services) internal static T? GetService<T>(this IServiceCollection services)
{ {
return services return services
.GetSingletonInstance<IAbpApplication>() .GetSingletonInstance<IAbpApplication>()
@ -102,7 +102,7 @@ public static class ServiceCollectionCommonExtensions
/// Resolves a dependency using given <see cref="IServiceCollection"/>. /// Resolves a dependency using given <see cref="IServiceCollection"/>.
/// This method should be used only after dependency injection registration phase completed. /// This method should be used only after dependency injection registration phase completed.
/// </summary> /// </summary>
internal static object GetService(this IServiceCollection services, Type type) internal static object? GetService(this IServiceCollection services, Type type)
{ {
return services return services
.GetSingletonInstance<IAbpApplication>() .GetSingletonInstance<IAbpApplication>()
@ -115,7 +115,7 @@ public static class ServiceCollectionCommonExtensions
/// Throws exception if service is not registered. /// Throws exception if service is not registered.
/// This method should be used only after dependency injection registration phase completed. /// This method should be used only after dependency injection registration phase completed.
/// </summary> /// </summary>
public static T GetRequiredService<T>(this IServiceCollection services) public static T GetRequiredService<T>(this IServiceCollection services) where T : notnull
{ {
return services return services
.GetSingletonInstance<IAbpApplication>() .GetSingletonInstance<IAbpApplication>()
@ -140,25 +140,25 @@ public static class ServiceCollectionCommonExtensions
/// Returns a <see cref="Lazy{T}"/> to resolve a service from given <see cref="IServiceCollection"/> /// Returns a <see cref="Lazy{T}"/> to resolve a service from given <see cref="IServiceCollection"/>
/// once dependency injection registration phase completed. /// once dependency injection registration phase completed.
/// </summary> /// </summary>
public static Lazy<T> GetServiceLazy<T>(this IServiceCollection services) public static Lazy<T?> GetServiceLazy<T>(this IServiceCollection services)
{ {
return new Lazy<T>(services.GetService<T>, true); return new Lazy<T?>(services.GetService<T>, true);
} }
/// <summary> /// <summary>
/// Returns a <see cref="Lazy{T}"/> to resolve a service from given <see cref="IServiceCollection"/> /// Returns a <see cref="Lazy{T}"/> to resolve a service from given <see cref="IServiceCollection"/>
/// once dependency injection registration phase completed. /// once dependency injection registration phase completed.
/// </summary> /// </summary>
public static Lazy<object> GetServiceLazy(this IServiceCollection services, Type type) public static Lazy<object?> GetServiceLazy(this IServiceCollection services, Type type)
{ {
return new Lazy<object>(() => services.GetService(type), true); return new Lazy<object?>(() => services.GetService(type), true);
} }
/// <summary> /// <summary>
/// Returns a <see cref="Lazy{T}"/> to resolve a service from given <see cref="IServiceCollection"/> /// Returns a <see cref="Lazy{T}"/> to resolve a service from given <see cref="IServiceCollection"/>
/// once dependency injection registration phase completed. /// once dependency injection registration phase completed.
/// </summary> /// </summary>
public static Lazy<T> GetRequiredServiceLazy<T>(this IServiceCollection services) public static Lazy<T> GetRequiredServiceLazy<T>(this IServiceCollection services) where T : notnull
{ {
return new Lazy<T>(services.GetRequiredService<T>, true); return new Lazy<T>(services.GetRequiredService<T>, true);
} }
@ -172,7 +172,7 @@ public static class ServiceCollectionCommonExtensions
return new Lazy<object>(() => services.GetRequiredService(type), true); return new Lazy<object>(() => services.GetRequiredService(type), true);
} }
public static IServiceProvider GetServiceProviderOrNull(this IServiceCollection services) public static IServiceProvider? GetServiceProviderOrNull(this IServiceCollection services)
{ {
return services.GetObjectOrNull<IServiceProvider>(); return services.GetObjectOrNull<IServiceProvider>();
} }

2
framework/src/Volo.Abp.Core/Microsoft/Extensions/DependencyInjection/ServiceCollectionConfigurationExtensions.cs

@ -21,7 +21,7 @@ public static class ServiceCollectionConfigurationExtensions
} }
[CanBeNull] [CanBeNull]
public static IConfiguration GetConfigurationOrNull(this IServiceCollection services) public static IConfiguration? GetConfigurationOrNull(this IServiceCollection services)
{ {
var hostBuilderContext = services.GetSingletonInstanceOrNull<HostBuilderContext>(); var hostBuilderContext = services.GetSingletonInstanceOrNull<HostBuilderContext>();
if (hostBuilderContext?.Configuration != null) if (hostBuilderContext?.Configuration != null)

2
framework/src/Volo.Abp.Core/Microsoft/Extensions/DependencyInjection/ServiceCollectionObjectAccessorExtensions.cs

@ -40,7 +40,7 @@ public static class ServiceCollectionObjectAccessorExtensions
return accessor; return accessor;
} }
public static T GetObjectOrNull<T>(this IServiceCollection services) public static T? GetObjectOrNull<T>(this IServiceCollection services)
where T : class where T : class
{ {
return services.GetSingletonInstanceOrNull<IObjectAccessor<T>>()?.Value; return services.GetSingletonInstanceOrNull<IObjectAccessor<T>>()?.Value;

17
framework/src/Volo.Abp.Core/Microsoft/Extensions/Logging/AbpLoggerExtensions.cs

@ -83,7 +83,7 @@ public static class AbpLoggerExtensions
private static void LogData(ILogger logger, Exception exception, LogLevel logLevel) private static void LogData(ILogger logger, Exception exception, LogLevel logLevel)
{ {
if (exception.Data == null || exception.Data.Count <= 0) if (exception.Data.Count <= 0)
{ {
return; return;
} }
@ -102,23 +102,22 @@ public static class AbpLoggerExtensions
{ {
var loggingExceptions = new List<IExceptionWithSelfLogging>(); var loggingExceptions = new List<IExceptionWithSelfLogging>();
if (exception is IExceptionWithSelfLogging) if (exception is IExceptionWithSelfLogging logging)
{ {
loggingExceptions.Add(exception as IExceptionWithSelfLogging); loggingExceptions.Add(logging);
} }
else if (exception is AggregateException && exception.InnerException != null) else if (exception is AggregateException aggException && aggException.InnerException != null)
{ {
var aggException = exception as AggregateException; if (aggException.InnerException is IExceptionWithSelfLogging selfLogging)
if (aggException.InnerException is IExceptionWithSelfLogging)
{ {
loggingExceptions.Add(aggException.InnerException as IExceptionWithSelfLogging); loggingExceptions.Add(selfLogging);
} }
foreach (var innerException in aggException.InnerExceptions) foreach (var innerException in aggException.InnerExceptions)
{ {
if (innerException is IExceptionWithSelfLogging) if (innerException is IExceptionWithSelfLogging withSelfLogging)
{ {
loggingExceptions.AddIfNotContains(innerException as IExceptionWithSelfLogging); loggingExceptions.AddIfNotContains(withSelfLogging);
} }
} }
} }

2
framework/src/Volo.Abp.Core/System/AbpObjectExtensions.cs

@ -36,7 +36,7 @@ public static class AbpObjectExtensions
{ {
if (typeof(T) == typeof(Guid)) if (typeof(T) == typeof(Guid))
{ {
return (T)TypeDescriptor.GetConverter(typeof(T)).ConvertFromInvariantString(obj.ToString()); return (T)TypeDescriptor.GetConverter(typeof(T)).ConvertFromInvariantString(obj.ToString()!)!;
} }
return (T)Convert.ChangeType(obj, typeof(T), CultureInfo.InvariantCulture); return (T)Convert.ChangeType(obj, typeof(T), CultureInfo.InvariantCulture);

12
framework/src/Volo.Abp.Core/System/AbpStringExtensions.cs

@ -47,7 +47,7 @@ public static class AbpStringExtensions
/// Indicates whether this string is null or an System.String.Empty string. /// Indicates whether this string is null or an System.String.Empty string.
/// </summary> /// </summary>
[ContractAnnotation("str:null => true")] [ContractAnnotation("str:null => true")]
public static bool IsNullOrEmpty(this string str) public static bool IsNullOrEmpty(this string? str)
{ {
return string.IsNullOrEmpty(str); return string.IsNullOrEmpty(str);
} }
@ -56,7 +56,7 @@ public static class AbpStringExtensions
/// indicates whether this string is null, empty, or consists only of white-space characters. /// indicates whether this string is null, empty, or consists only of white-space characters.
/// </summary> /// </summary>
[ContractAnnotation("str:null => true")] [ContractAnnotation("str:null => true")]
public static bool IsNullOrWhiteSpace(this string str) public static bool IsNullOrWhiteSpace(this string? str)
{ {
return string.IsNullOrWhiteSpace(str); return string.IsNullOrWhiteSpace(str);
} }
@ -482,7 +482,7 @@ public static class AbpStringExtensions
/// Gets a substring of a string from beginning of the string if it exceeds maximum length. /// Gets a substring of a string from beginning of the string if it exceeds maximum length.
/// </summary> /// </summary>
[ContractAnnotation("null <= str:null")] [ContractAnnotation("null <= str:null")]
public static string Truncate(this string str, int maxLength) public static string? Truncate(this string? str, int maxLength)
{ {
if (str == null) if (str == null)
{ {
@ -501,7 +501,7 @@ public static class AbpStringExtensions
/// Gets a substring of a string from Ending of the string if it exceeds maximum length. /// Gets a substring of a string from Ending of the string if it exceeds maximum length.
/// </summary> /// </summary>
[ContractAnnotation("null <= str:null")] [ContractAnnotation("null <= str:null")]
public static string TruncateFromBeginning(this string str, int maxLength) public static string? TruncateFromBeginning(this string? str, int maxLength)
{ {
if (str == null) if (str == null)
{ {
@ -522,7 +522,7 @@ public static class AbpStringExtensions
/// Returning string can not be longer than maxLength. /// Returning string can not be longer than maxLength.
/// </summary> /// </summary>
/// <exception cref="ArgumentNullException">Thrown if <paramref name="str"/> is null</exception> /// <exception cref="ArgumentNullException">Thrown if <paramref name="str"/> is null</exception>
public static string TruncateWithPostfix(this string str, int maxLength) public static string? TruncateWithPostfix(this string? str, int maxLength)
{ {
return TruncateWithPostfix(str, maxLength, "..."); return TruncateWithPostfix(str, maxLength, "...");
} }
@ -534,7 +534,7 @@ public static class AbpStringExtensions
/// </summary> /// </summary>
/// <exception cref="ArgumentNullException">Thrown if <paramref name="str"/> is null</exception> /// <exception cref="ArgumentNullException">Thrown if <paramref name="str"/> is null</exception>
[ContractAnnotation("null <= str:null")] [ContractAnnotation("null <= str:null")]
public static string TruncateWithPostfix(this string str, int maxLength, string postfix) public static string? TruncateWithPostfix(this string? str, int maxLength, string postfix)
{ {
if (str == null) if (str == null)
{ {

4
framework/src/Volo.Abp.Core/System/AbpTypeExtensions.cs

@ -72,9 +72,9 @@ public static class AbpTypeExtensions
private static void AddTypeAndBaseTypesRecursively( private static void AddTypeAndBaseTypesRecursively(
[NotNull] List<Type> types, [NotNull] List<Type> types,
[CanBeNull] Type type, Type? type,
bool includeObject, bool includeObject,
[CanBeNull] Type stoppingType = null) Type? stoppingType = null)
{ {
if (type == null || type == stoppingType) if (type == null || type == stoppingType)
{ {

2
framework/src/Volo.Abp.Core/System/Collections/Generic/AbpCollectionExtensions.cs

@ -13,7 +13,7 @@ public static class AbpCollectionExtensions
/// Checks whatever given collection object is null or has no item. /// Checks whatever given collection object is null or has no item.
/// </summary> /// </summary>
[ContractAnnotation("source:null => true")] [ContractAnnotation("source:null => true")]
public static bool IsNullOrEmpty<T>([CanBeNull] this ICollection<T> source) public static bool IsNullOrEmpty<T>(this ICollection<T>? source)
{ {
return source == null || source.Count <= 0; return source == null || source.Count <= 0;
} }

20
framework/src/Volo.Abp.Core/System/Collections/Generic/AbpDictionaryExtensions.cs

@ -16,9 +16,9 @@ public static class AbpDictionaryExtensions
/// <param name="key">Key</param> /// <param name="key">Key</param>
/// <param name="value">Value of the key (or default value if key not exists)</param> /// <param name="value">Value of the key (or default value if key not exists)</param>
/// <returns>True if key does exists in the dictionary</returns> /// <returns>True if key does exists in the dictionary</returns>
internal static bool TryGetValue<T>(this IDictionary<string, object> dictionary, string key, out T value) internal static bool TryGetValue<T>(this IDictionary<string, object> dictionary, string key, out T? value)
{ {
object valueObj; object? valueObj;
if (dictionary.TryGetValue(key, out valueObj) && valueObj is T) if (dictionary.TryGetValue(key, out valueObj) && valueObj is T)
{ {
value = (T)valueObj; value = (T)valueObj;
@ -37,9 +37,9 @@ public static class AbpDictionaryExtensions
/// <typeparam name="TKey">Type of the key</typeparam> /// <typeparam name="TKey">Type of the key</typeparam>
/// <typeparam name="TValue">Type of the value</typeparam> /// <typeparam name="TValue">Type of the value</typeparam>
/// <returns>Value if found, default if can not found.</returns> /// <returns>Value if found, default if can not found.</returns>
public static TValue GetOrDefault<TKey, TValue>(this Dictionary<TKey, TValue> dictionary, TKey key) public static TValue? GetOrDefault<TKey, TValue>(this Dictionary<TKey, TValue> dictionary, TKey key) where TKey : notnull
{ {
TValue obj; TValue? obj;
return dictionary.TryGetValue(key, out obj) ? obj : default; return dictionary.TryGetValue(key, out obj) ? obj : default;
} }
@ -51,7 +51,7 @@ public static class AbpDictionaryExtensions
/// <typeparam name="TKey">Type of the key</typeparam> /// <typeparam name="TKey">Type of the key</typeparam>
/// <typeparam name="TValue">Type of the value</typeparam> /// <typeparam name="TValue">Type of the value</typeparam>
/// <returns>Value if found, default if can not found.</returns> /// <returns>Value if found, default if can not found.</returns>
public static TValue GetOrDefault<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key) public static TValue? GetOrDefault<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key)
{ {
return dictionary.TryGetValue(key, out var obj) ? obj : default; return dictionary.TryGetValue(key, out var obj) ? obj : default;
} }
@ -64,7 +64,7 @@ public static class AbpDictionaryExtensions
/// <typeparam name="TKey">Type of the key</typeparam> /// <typeparam name="TKey">Type of the key</typeparam>
/// <typeparam name="TValue">Type of the value</typeparam> /// <typeparam name="TValue">Type of the value</typeparam>
/// <returns>Value if found, default if can not found.</returns> /// <returns>Value if found, default if can not found.</returns>
public static TValue GetOrDefault<TKey, TValue>(this IReadOnlyDictionary<TKey, TValue> dictionary, TKey key) public static TValue? GetOrDefault<TKey, TValue>(this IReadOnlyDictionary<TKey, TValue> dictionary, TKey key)
{ {
return dictionary.TryGetValue(key, out var obj) ? obj : default; return dictionary.TryGetValue(key, out var obj) ? obj : default;
} }
@ -77,7 +77,7 @@ public static class AbpDictionaryExtensions
/// <typeparam name="TKey">Type of the key</typeparam> /// <typeparam name="TKey">Type of the key</typeparam>
/// <typeparam name="TValue">Type of the value</typeparam> /// <typeparam name="TValue">Type of the value</typeparam>
/// <returns>Value if found, default if can not found.</returns> /// <returns>Value if found, default if can not found.</returns>
public static TValue GetOrDefault<TKey, TValue>(this ConcurrentDictionary<TKey, TValue> dictionary, TKey key) public static TValue? GetOrDefault<TKey, TValue>(this ConcurrentDictionary<TKey, TValue> dictionary, TKey key) where TKey : notnull
{ {
return dictionary.TryGetValue(key, out var obj) ? obj : default; return dictionary.TryGetValue(key, out var obj) ? obj : default;
} }
@ -93,7 +93,7 @@ public static class AbpDictionaryExtensions
/// <returns>Value if found, default if can not found.</returns> /// <returns>Value if found, default if can not found.</returns>
public static TValue GetOrAdd<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key, Func<TKey, TValue> factory) public static TValue GetOrAdd<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key, Func<TKey, TValue> factory)
{ {
TValue obj; TValue? obj;
if (dictionary.TryGetValue(key, out obj)) if (dictionary.TryGetValue(key, out obj))
{ {
return obj; return obj;
@ -125,7 +125,7 @@ public static class AbpDictionaryExtensions
/// <typeparam name="TKey">Type of the key</typeparam> /// <typeparam name="TKey">Type of the key</typeparam>
/// <typeparam name="TValue">Type of the value</typeparam> /// <typeparam name="TValue">Type of the value</typeparam>
/// <returns>Value if found, default if can not found.</returns> /// <returns>Value if found, default if can not found.</returns>
public static TValue GetOrAdd<TKey, TValue>(this ConcurrentDictionary<TKey, TValue> dictionary, TKey key, Func<TValue> factory) public static TValue GetOrAdd<TKey, TValue>(this ConcurrentDictionary<TKey, TValue> dictionary, TKey key, Func<TValue> factory) where TKey : notnull
{ {
return dictionary.GetOrAdd(key, k => factory()); return dictionary.GetOrAdd(key, k => factory());
} }
@ -138,7 +138,7 @@ public static class AbpDictionaryExtensions
public static dynamic ConvertToDynamicObject(this Dictionary<string, object> dictionary) public static dynamic ConvertToDynamicObject(this Dictionary<string, object> dictionary)
{ {
var expandoObject = new ExpandoObject(); var expandoObject = new ExpandoObject();
var expendObjectCollection = (ICollection<KeyValuePair<string, object>>)expandoObject; var expendObjectCollection = (ICollection<KeyValuePair<string, object>>)expandoObject!;
foreach (var keyValuePair in dictionary) foreach (var keyValuePair in dictionary)
{ {

4
framework/src/Volo.Abp.Core/System/Collections/Generic/AbpListExtensions.cs

@ -196,7 +196,7 @@ public static class AbpListExtensions
public static List<T> SortByDependencies<T>( public static List<T> SortByDependencies<T>(
this IEnumerable<T> source, this IEnumerable<T> source,
Func<T, IEnumerable<T>> getDependencies, Func<T, IEnumerable<T>> getDependencies,
IEqualityComparer<T> comparer = null) IEqualityComparer<T>? comparer = null) where T : notnull
{ {
/* See: http://www.codeproject.com/Articles/869059/Topological-sorting-in-Csharp /* See: http://www.codeproject.com/Articles/869059/Topological-sorting-in-Csharp
* http://en.wikipedia.org/wiki/Topological_sorting * http://en.wikipedia.org/wiki/Topological_sorting
@ -222,7 +222,7 @@ public static class AbpListExtensions
/// <param name="sorted">List with the sortet items</param> /// <param name="sorted">List with the sortet items</param>
/// <param name="visited">Dictionary with the visited items</param> /// <param name="visited">Dictionary with the visited items</param>
private static void SortByDependenciesVisit<T>(T item, Func<T, IEnumerable<T>> getDependencies, List<T> sorted, private static void SortByDependenciesVisit<T>(T item, Func<T, IEnumerable<T>> getDependencies, List<T> sorted,
Dictionary<T, bool> visited) Dictionary<T, bool> visited) where T : notnull
{ {
bool inProcess; bool inProcess;
var alreadyVisited = visited.TryGetValue(item, out inProcess); var alreadyVisited = visited.TryGetValue(item, out inProcess);

24
framework/src/Volo.Abp.Core/System/Linq/PredicateOperator.cs

@ -42,7 +42,7 @@ public static class PredicateBuilder
} }
/// <summary> Start an expression </summary> /// <summary> Start an expression </summary>
public static ExpressionStarter<T> New<T>(Expression<Func<T, bool>> expr = null) public static ExpressionStarter<T> New<T>(Expression<Func<T, bool>>? expr = null)
{ {
return new ExpressionStarter<T>(expr); return new ExpressionStarter<T>(expr);
} }
@ -58,7 +58,7 @@ public static class PredicateBuilder
[NotNull] Expression<Func<T, bool>> expr2) [NotNull] Expression<Func<T, bool>> expr2)
{ {
var expr2Body = new RebindParameterVisitor(expr2.Parameters[0], expr1.Parameters[0]).Visit(expr2.Body); var expr2Body = new RebindParameterVisitor(expr2.Parameters[0], expr1.Parameters[0]).Visit(expr2.Body);
return Expression.Lambda<Func<T, bool>>(Expression.OrElse(expr1.Body, expr2Body), expr1.Parameters); return Expression.Lambda<Func<T, bool>>(Expression.OrElse(expr1.Body, expr2Body!), expr1.Parameters);
} }
/// <summary> AND </summary> /// <summary> AND </summary>
@ -66,7 +66,7 @@ public static class PredicateBuilder
[NotNull] Expression<Func<T, bool>> expr2) [NotNull] Expression<Func<T, bool>> expr2)
{ {
var expr2Body = new RebindParameterVisitor(expr2.Parameters[0], expr1.Parameters[0]).Visit(expr2.Body); var expr2Body = new RebindParameterVisitor(expr2.Parameters[0], expr1.Parameters[0]).Visit(expr2.Body);
return Expression.Lambda<Func<T, bool>>(Expression.AndAlso(expr1.Body, expr2Body), expr1.Parameters); return Expression.Lambda<Func<T, bool>>(Expression.AndAlso(expr1.Body, expr2Body!), expr1.Parameters);
} }
/// <summary> /// <summary>
@ -120,16 +120,16 @@ public class ExpressionStarter<T>
} }
} }
public ExpressionStarter(Expression<Func<T, bool>> exp) : this(false) public ExpressionStarter(Expression<Func<T, bool>>? exp) : this(false)
{ {
_predicate = exp; _predicate = exp;
} }
/// <summary>The actual Predicate. It can only be set by calling Start.</summary> /// <summary>The actual Predicate. It can only be set by calling Start.</summary>
private Expression<Func<T, bool>> Predicate => private Expression<Func<T, bool>> Predicate =>
(IsStarted || !UseDefaultExpression) ? _predicate : DefaultExpression; ((IsStarted || !UseDefaultExpression) ? _predicate : DefaultExpression)!;
private Expression<Func<T, bool>> _predicate; private Expression<Func<T, bool>>? _predicate;
/// <summary>Determines if the predicate is started.</summary> /// <summary>Determines if the predicate is started.</summary>
public bool IsStarted => _predicate != null; public bool IsStarted => _predicate != null;
@ -138,7 +138,7 @@ public class ExpressionStarter<T>
public bool UseDefaultExpression => DefaultExpression != null; public bool UseDefaultExpression => DefaultExpression != null;
/// <summary>The default expression</summary> /// <summary>The default expression</summary>
public Expression<Func<T, bool>> DefaultExpression { get; set; } public Expression<Func<T, bool>>? DefaultExpression { get; set; }
/// <summary>Set the Expression predicate</summary> /// <summary>Set the Expression predicate</summary>
/// <param name="exp">The first expression</param> /// <param name="exp">The first expression</param>
@ -165,7 +165,7 @@ public class ExpressionStarter<T>
} }
/// <summary> Show predicate string </summary> /// <summary> Show predicate string </summary>
public override string ToString() public override string? ToString()
{ {
return Predicate?.ToString(); return Predicate?.ToString();
} }
@ -176,7 +176,7 @@ public class ExpressionStarter<T>
/// Allows this object to be implicitely converted to an Expression{Func{T, bool}}. /// Allows this object to be implicitely converted to an Expression{Func{T, bool}}.
/// </summary> /// </summary>
/// <param name="right"></param> /// <param name="right"></param>
public static implicit operator Expression<Func<T, bool>>(ExpressionStarter<T> right) public static implicit operator Expression<Func<T, bool>>?(ExpressionStarter<T>? right)
{ {
return right?.Predicate; return right?.Predicate;
} }
@ -185,7 +185,7 @@ public class ExpressionStarter<T>
/// Allows this object to be implicitely converted to an Expression{Func{T, bool}}. /// Allows this object to be implicitely converted to an Expression{Func{T, bool}}.
/// </summary> /// </summary>
/// <param name="right"></param> /// <param name="right"></param>
public static implicit operator Func<T, bool>(ExpressionStarter<T> right) public static implicit operator Func<T, bool>?(ExpressionStarter<T>? right)
{ {
return right == null ? null : return right == null ? null :
(right.IsStarted || right.UseDefaultExpression) ? right.Predicate.Compile() : null; (right.IsStarted || right.UseDefaultExpression) ? right.Predicate.Compile() : null;
@ -195,7 +195,7 @@ public class ExpressionStarter<T>
/// Allows this object to be implicitely converted to an Expression{Func{T, bool}}. /// Allows this object to be implicitely converted to an Expression{Func{T, bool}}.
/// </summary> /// </summary>
/// <param name="right"></param> /// <param name="right"></param>
public static implicit operator ExpressionStarter<T>(Expression<Func<T, bool>> right) public static implicit operator ExpressionStarter<T>?(Expression<Func<T, bool>>? right)
{ {
return right == null ? null : new ExpressionStarter<T>(right); return right == null ? null : new ExpressionStarter<T>(right);
} }
@ -240,7 +240,7 @@ public class ExpressionStarter<T>
#if !(NET35) #if !(NET35)
/// <summary></summary> /// <summary></summary>
public string Name => Predicate.Name; public string? Name => Predicate.Name;
/// <summary></summary> /// <summary></summary>
public Type ReturnType => Predicate.ReturnType; public Type ReturnType => Predicate.ReturnType;

2
framework/src/Volo.Abp.Core/System/Reflection/AbpAssemblyExtensions.cs

@ -6,6 +6,6 @@ public static class AbpAssemblyExtensions
{ {
public static string GetFileVersion(this Assembly assembly) public static string GetFileVersion(this Assembly assembly)
{ {
return FileVersionInfo.GetVersionInfo(assembly.Location).FileVersion; return FileVersionInfo.GetVersionInfo(assembly.Location).FileVersion!;
} }
} }

6
framework/src/Volo.Abp.Core/System/Reflection/AbpMemberInfoExtensions.cs

@ -14,7 +14,7 @@ public static class AbpMemberInfoExtensions
/// <param name="memberInfo">The member that will be checked for the attribute</param> /// <param name="memberInfo">The member that will be checked for the attribute</param>
/// <param name="inherit">Include inherited attributes</param> /// <param name="inherit">Include inherited attributes</param>
/// <returns>Returns the attribute object if found. Returns null if not found.</returns> /// <returns>Returns the attribute object if found. Returns null if not found.</returns>
public static TAttribute GetSingleAttributeOrNull<TAttribute>(this MemberInfo memberInfo, bool inherit = true) public static TAttribute? GetSingleAttributeOrNull<TAttribute>(this MemberInfo memberInfo, bool inherit = true)
where TAttribute : Attribute where TAttribute : Attribute
{ {
if (memberInfo == null) if (memberInfo == null)
@ -32,7 +32,7 @@ public static class AbpMemberInfoExtensions
} }
public static TAttribute GetSingleAttributeOfTypeOrBaseTypesOrNull<TAttribute>(this Type type, bool inherit = true) public static TAttribute? GetSingleAttributeOfTypeOrBaseTypesOrNull<TAttribute>(this Type type, bool inherit = true)
where TAttribute : Attribute where TAttribute : Attribute
{ {
var attr = type.GetTypeInfo().GetSingleAttributeOrNull<TAttribute>(); var attr = type.GetTypeInfo().GetSingleAttributeOrNull<TAttribute>();
@ -46,6 +46,6 @@ public static class AbpMemberInfoExtensions
return null; return null;
} }
return type.GetTypeInfo().BaseType.GetSingleAttributeOfTypeOrBaseTypesOrNull<TAttribute>(inherit); return type.GetTypeInfo().BaseType?.GetSingleAttributeOfTypeOrBaseTypesOrNull<TAttribute>(inherit);
} }
} }

2
framework/src/Volo.Abp.Core/Volo.Abp.Core.csproj

@ -5,6 +5,8 @@
<PropertyGroup> <PropertyGroup>
<TargetFrameworks>netstandard2.0;netstandard2.1;net7.0</TargetFrameworks> <TargetFrameworks>netstandard2.0;netstandard2.1;net7.0</TargetFrameworks>
<Nullable>enable</Nullable>
<WarningsAsErrors>Nullable</WarningsAsErrors>
<AssemblyName>Volo.Abp.Core</AssemblyName> <AssemblyName>Volo.Abp.Core</AssemblyName>
<PackageId>Volo.Abp.Core</PackageId> <PackageId>Volo.Abp.Core</PackageId>
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback> <AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback>

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

@ -19,13 +19,13 @@ public abstract class AbpApplicationBase : IAbpApplication
[NotNull] [NotNull]
public Type StartupModuleType { get; } public Type StartupModuleType { get; }
public IServiceProvider ServiceProvider { get; private set; } public IServiceProvider ServiceProvider { get; private set; } = default!;
public IServiceCollection Services { get; } public IServiceCollection Services { get; }
public IReadOnlyList<IAbpModuleDescriptor> Modules { get; } public IReadOnlyList<IAbpModuleDescriptor> Modules { get; }
public string ApplicationName { get; } public string? ApplicationName { get; }
public string InstanceId { get; } = Guid.NewGuid().ToString(); public string InstanceId { get; } = Guid.NewGuid().ToString();
@ -34,7 +34,7 @@ public abstract class AbpApplicationBase : IAbpApplication
internal AbpApplicationBase( internal AbpApplicationBase(
[NotNull] Type startupModuleType, [NotNull] Type startupModuleType,
[NotNull] IServiceCollection services, [NotNull] IServiceCollection services,
[CanBeNull] Action<AbpApplicationCreationOptions> optionsAction) Action<AbpApplicationCreationOptions>? optionsAction)
{ {
Check.NotNull(startupModuleType, nameof(startupModuleType)); Check.NotNull(startupModuleType, nameof(startupModuleType));
Check.NotNull(services, nameof(services)); Check.NotNull(services, nameof(services));
@ -224,7 +224,7 @@ public abstract class AbpApplicationBase : IAbpApplication
{ {
if (module.Instance is AbpModule abpModule) if (module.Instance is AbpModule abpModule)
{ {
abpModule.ServiceConfigurationContext = null; abpModule.ServiceConfigurationContext = null!;
} }
} }
@ -315,7 +315,7 @@ public abstract class AbpApplicationBase : IAbpApplication
{ {
if (module.Instance is AbpModule abpModule) if (module.Instance is AbpModule abpModule)
{ {
abpModule.ServiceConfigurationContext = null; abpModule.ServiceConfigurationContext = null!;
} }
} }
@ -324,11 +324,11 @@ public abstract class AbpApplicationBase : IAbpApplication
TryToSetEnvironment(Services); TryToSetEnvironment(Services);
} }
private static string GetApplicationName(AbpApplicationCreationOptions options) private static string? GetApplicationName(AbpApplicationCreationOptions options)
{ {
if (!string.IsNullOrWhiteSpace(options.ApplicationName)) if (!string.IsNullOrWhiteSpace(options.ApplicationName))
{ {
return options.ApplicationName; return options.ApplicationName!;
} }
var configuration = options.Services.GetConfigurationOrNull(); var configuration = options.Services.GetConfigurationOrNull();
@ -337,7 +337,7 @@ public abstract class AbpApplicationBase : IAbpApplication
var appNameConfig = configuration["ApplicationName"]; var appNameConfig = configuration["ApplicationName"];
if (!string.IsNullOrWhiteSpace(appNameConfig)) if (!string.IsNullOrWhiteSpace(appNameConfig))
{ {
return appNameConfig; return appNameConfig!;
} }
} }

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

@ -21,11 +21,9 @@ public class AbpApplicationCreationOptions
public bool SkipConfigureServices { get; set; } public bool SkipConfigureServices { get; set; }
[CanBeNull] public string? ApplicationName { get; set; }
public string ApplicationName { get; set; }
[CanBeNull] public string? Environment { get; set; }
public string Environment { get; set; }
public AbpApplicationCreationOptions([NotNull] IServiceCollection services) public AbpApplicationCreationOptions([NotNull] IServiceCollection services)
{ {

16
framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationFactory.cs

@ -9,7 +9,7 @@ namespace Volo.Abp;
public static class AbpApplicationFactory public static class AbpApplicationFactory
{ {
public async static Task<IAbpApplicationWithInternalServiceProvider> CreateAsync<TStartupModule>( public async static Task<IAbpApplicationWithInternalServiceProvider> CreateAsync<TStartupModule>(
[CanBeNull] Action<AbpApplicationCreationOptions> optionsAction = null) Action<AbpApplicationCreationOptions>? optionsAction = null)
where TStartupModule : IAbpModule where TStartupModule : IAbpModule
{ {
var app = Create(typeof(TStartupModule), options => var app = Create(typeof(TStartupModule), options =>
@ -23,7 +23,7 @@ public static class AbpApplicationFactory
public async static Task<IAbpApplicationWithInternalServiceProvider> CreateAsync( public async static Task<IAbpApplicationWithInternalServiceProvider> CreateAsync(
[NotNull] Type startupModuleType, [NotNull] Type startupModuleType,
[CanBeNull] Action<AbpApplicationCreationOptions> optionsAction = null) Action<AbpApplicationCreationOptions>? optionsAction = null)
{ {
var app = new AbpApplicationWithInternalServiceProvider(startupModuleType, options => var app = new AbpApplicationWithInternalServiceProvider(startupModuleType, options =>
{ {
@ -36,7 +36,7 @@ public static class AbpApplicationFactory
public async static Task<IAbpApplicationWithExternalServiceProvider> CreateAsync<TStartupModule>( public async static Task<IAbpApplicationWithExternalServiceProvider> CreateAsync<TStartupModule>(
[NotNull] IServiceCollection services, [NotNull] IServiceCollection services,
[CanBeNull] Action<AbpApplicationCreationOptions> optionsAction = null) Action<AbpApplicationCreationOptions>? optionsAction = null)
where TStartupModule : IAbpModule where TStartupModule : IAbpModule
{ {
var app = Create(typeof(TStartupModule), services, options => var app = Create(typeof(TStartupModule), services, options =>
@ -51,7 +51,7 @@ public static class AbpApplicationFactory
public async static Task<IAbpApplicationWithExternalServiceProvider> CreateAsync( public async static Task<IAbpApplicationWithExternalServiceProvider> CreateAsync(
[NotNull] Type startupModuleType, [NotNull] Type startupModuleType,
[NotNull] IServiceCollection services, [NotNull] IServiceCollection services,
[CanBeNull] Action<AbpApplicationCreationOptions> optionsAction = null) Action<AbpApplicationCreationOptions>? optionsAction = null)
{ {
var app = new AbpApplicationWithExternalServiceProvider(startupModuleType, services, options => var app = new AbpApplicationWithExternalServiceProvider(startupModuleType, services, options =>
{ {
@ -63,7 +63,7 @@ public static class AbpApplicationFactory
} }
public static IAbpApplicationWithInternalServiceProvider Create<TStartupModule>( public static IAbpApplicationWithInternalServiceProvider Create<TStartupModule>(
[CanBeNull] Action<AbpApplicationCreationOptions> optionsAction = null) Action<AbpApplicationCreationOptions>? optionsAction = null)
where TStartupModule : IAbpModule where TStartupModule : IAbpModule
{ {
return Create(typeof(TStartupModule), optionsAction); return Create(typeof(TStartupModule), optionsAction);
@ -71,14 +71,14 @@ public static class AbpApplicationFactory
public static IAbpApplicationWithInternalServiceProvider Create( public static IAbpApplicationWithInternalServiceProvider Create(
[NotNull] Type startupModuleType, [NotNull] Type startupModuleType,
[CanBeNull] Action<AbpApplicationCreationOptions> optionsAction = null) Action<AbpApplicationCreationOptions>? optionsAction = null)
{ {
return new AbpApplicationWithInternalServiceProvider(startupModuleType, optionsAction); return new AbpApplicationWithInternalServiceProvider(startupModuleType, optionsAction);
} }
public static IAbpApplicationWithExternalServiceProvider Create<TStartupModule>( public static IAbpApplicationWithExternalServiceProvider Create<TStartupModule>(
[NotNull] IServiceCollection services, [NotNull] IServiceCollection services,
[CanBeNull] Action<AbpApplicationCreationOptions> optionsAction = null) Action<AbpApplicationCreationOptions>? optionsAction = null)
where TStartupModule : IAbpModule where TStartupModule : IAbpModule
{ {
return Create(typeof(TStartupModule), services, optionsAction); return Create(typeof(TStartupModule), services, optionsAction);
@ -87,7 +87,7 @@ public static class AbpApplicationFactory
public static IAbpApplicationWithExternalServiceProvider Create( public static IAbpApplicationWithExternalServiceProvider Create(
[NotNull] Type startupModuleType, [NotNull] Type startupModuleType,
[NotNull] IServiceCollection services, [NotNull] IServiceCollection services,
[CanBeNull] Action<AbpApplicationCreationOptions> optionsAction = null) Action<AbpApplicationCreationOptions>? optionsAction = null)
{ {
return new AbpApplicationWithExternalServiceProvider(startupModuleType, services, optionsAction); return new AbpApplicationWithExternalServiceProvider(startupModuleType, services, optionsAction);
} }

3
framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationWithExternalServiceProvider.cs

@ -10,7 +10,7 @@ internal class AbpApplicationWithExternalServiceProvider : AbpApplicationBase, I
public AbpApplicationWithExternalServiceProvider( public AbpApplicationWithExternalServiceProvider(
[NotNull] Type startupModuleType, [NotNull] Type startupModuleType,
[NotNull] IServiceCollection services, [NotNull] IServiceCollection services,
[CanBeNull] Action<AbpApplicationCreationOptions> optionsAction Action<AbpApplicationCreationOptions>? optionsAction
) : base( ) : base(
startupModuleType, startupModuleType,
services, services,
@ -23,6 +23,7 @@ internal class AbpApplicationWithExternalServiceProvider : AbpApplicationBase, I
{ {
Check.NotNull(serviceProvider, nameof(serviceProvider)); Check.NotNull(serviceProvider, nameof(serviceProvider));
// ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract
if (ServiceProvider != null) if (ServiceProvider != null)
{ {
if (ServiceProvider != serviceProvider) if (ServiceProvider != serviceProvider)

9
framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationWithInternalServiceProvider.cs

@ -7,11 +7,11 @@ namespace Volo.Abp;
internal class AbpApplicationWithInternalServiceProvider : AbpApplicationBase, IAbpApplicationWithInternalServiceProvider internal class AbpApplicationWithInternalServiceProvider : AbpApplicationBase, IAbpApplicationWithInternalServiceProvider
{ {
public IServiceScope ServiceScope { get; private set; } public IServiceScope? ServiceScope { get; private set; }
public AbpApplicationWithInternalServiceProvider( public AbpApplicationWithInternalServiceProvider(
[NotNull] Type startupModuleType, [NotNull] Type startupModuleType,
[CanBeNull] Action<AbpApplicationCreationOptions> optionsAction Action<AbpApplicationCreationOptions>? optionsAction
) : this( ) : this(
startupModuleType, startupModuleType,
new ServiceCollection(), new ServiceCollection(),
@ -23,7 +23,7 @@ internal class AbpApplicationWithInternalServiceProvider : AbpApplicationBase, I
private AbpApplicationWithInternalServiceProvider( private AbpApplicationWithInternalServiceProvider(
[NotNull] Type startupModuleType, [NotNull] Type startupModuleType,
[NotNull] IServiceCollection services, [NotNull] IServiceCollection services,
[CanBeNull] Action<AbpApplicationCreationOptions> optionsAction Action<AbpApplicationCreationOptions>? optionsAction
) : base( ) : base(
startupModuleType, startupModuleType,
services, services,
@ -34,6 +34,7 @@ internal class AbpApplicationWithInternalServiceProvider : AbpApplicationBase, I
public IServiceProvider CreateServiceProvider() public IServiceProvider CreateServiceProvider()
{ {
// ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract
if (ServiceProvider != null) if (ServiceProvider != null)
{ {
return ServiceProvider; return ServiceProvider;
@ -42,7 +43,7 @@ internal class AbpApplicationWithInternalServiceProvider : AbpApplicationBase, I
ServiceScope = Services.BuildServiceProviderFromFactory().CreateScope(); ServiceScope = Services.BuildServiceProviderFromFactory().CreateScope();
SetServiceProvider(ServiceScope.ServiceProvider); SetServiceProvider(ServiceScope.ServiceProvider);
return ServiceProvider; return ServiceProvider!;
} }
public async Task InitializeAsync() public async Task InitializeAsync()

2
framework/src/Volo.Abp.Core/Volo/Abp/AbpHostEnvironment.cs

@ -2,5 +2,5 @@
public class AbpHostEnvironment : IAbpHostEnvironment public class AbpHostEnvironment : IAbpHostEnvironment
{ {
public string EnvironmentName { get; set; } public string? EnvironmentName { get; set; }
} }

2
framework/src/Volo.Abp.Core/Volo/Abp/Bundling/BundleContext.cs

@ -14,7 +14,7 @@ public class BundleContext
} }
public void Add(string source, bool excludeFromBundle = false, public void Add(string source, bool excludeFromBundle = false,
Dictionary<string, string> additionalProperties = null) Dictionary<string, string>? additionalProperties = null)
{ {
var bundleDefinition = new BundleDefinition var bundleDefinition = new BundleDefinition
{ {

2
framework/src/Volo.Abp.Core/Volo/Abp/Bundling/BundleDefinition.cs

@ -4,7 +4,7 @@ namespace Volo.Abp.Bundling;
public class BundleDefinition public class BundleDefinition
{ {
public string Source { get; set; } public string Source { get; set; } = default!;
public Dictionary<string, string> AdditionalProperties { get; set; } public Dictionary<string, string> AdditionalProperties { get; set; }

12
framework/src/Volo.Abp.Core/Volo/Abp/BusinessException.cs

@ -13,17 +13,17 @@ public class BusinessException : Exception,
IHasErrorDetails, IHasErrorDetails,
IHasLogLevel IHasLogLevel
{ {
public string Code { get; set; } public string? Code { get; set; }
public string Details { get; set; } public string? Details { get; set; }
public LogLevel LogLevel { get; set; } public LogLevel LogLevel { get; set; }
public BusinessException( public BusinessException(
string code = null, string? code = null,
string message = null, string? message = null,
string details = null, string? details = null,
Exception innerException = null, Exception? innerException = null,
LogLevel logLevel = LogLevel.Warning) LogLevel logLevel = LogLevel.Warning)
: base(message, innerException) : base(message, innerException)
{ {

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

@ -136,8 +136,8 @@ public static class Check
return type; return type;
} }
public static string Length( public static string? Length(
[CanBeNull] string value, string? value,
[InvokerParameterName][NotNull] string parameterName, [InvokerParameterName][NotNull] string parameterName,
int maxLength, int maxLength,
int minLength = 0) int minLength = 0)
@ -149,7 +149,7 @@ public static class Check
throw new ArgumentException(parameterName + " can not be null or empty!", parameterName); throw new ArgumentException(parameterName + " can not be null or empty!", parameterName);
} }
if (value.Length < minLength) if (value!.Length < minLength)
{ {
throw new ArgumentException($"{parameterName} length must be equal to or bigger than {minLength}!", parameterName); throw new ArgumentException($"{parameterName} length must be equal to or bigger than {minLength}!", parameterName);
} }

2
framework/src/Volo.Abp.Core/Volo/Abp/Content/IRemoteStreamContent.cs

@ -5,7 +5,7 @@ namespace Volo.Abp.Content;
public interface IRemoteStreamContent : IDisposable public interface IRemoteStreamContent : IDisposable
{ {
string FileName { get; } string? FileName { get; }
string ContentType { get; } string ContentType { get; }

4
framework/src/Volo.Abp.Core/Volo/Abp/Content/RemoteStreamContent.cs

@ -8,13 +8,13 @@ public class RemoteStreamContent : IRemoteStreamContent
private readonly bool _disposeStream; private readonly bool _disposeStream;
private bool _disposed; private bool _disposed;
public virtual string FileName { get; } public virtual string? FileName { get; }
public virtual string ContentType { get; } = "application/octet-stream"; public virtual string ContentType { get; } = "application/octet-stream";
public virtual long? ContentLength { get; } public virtual long? ContentLength { get; }
public RemoteStreamContent(Stream stream, string fileName = null, string contentType = null, long? readOnlyLength = null, bool disposeStream = true) public RemoteStreamContent(Stream stream, string? fileName = null, string? contentType = null, long? readOnlyLength = null, bool disposeStream = true)
{ {
_stream = stream; _stream = stream;

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

@ -28,12 +28,12 @@ public class AbpLazyServiceProvider :
return this.GetRequiredService(serviceType); return this.GetRequiredService(serviceType);
} }
public virtual T LazyGetService<T>() public virtual T? LazyGetService<T>()
{ {
return (T)LazyGetService(typeof(T)); return (T?)LazyGetService(typeof(T));
} }
public virtual object LazyGetService(Type serviceType) public virtual object? LazyGetService(Type serviceType)
{ {
return GetService(serviceType); return GetService(serviceType);
} }

16
framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/CachedServiceProviderBase.cs

@ -6,26 +6,26 @@ namespace Volo.Abp.DependencyInjection;
public abstract class CachedServiceProviderBase : ICachedServiceProviderBase public abstract class CachedServiceProviderBase : ICachedServiceProviderBase
{ {
protected IServiceProvider ServiceProvider { get; } protected IServiceProvider ServiceProvider { get; }
protected ConcurrentDictionary<Type, Lazy<object>> CachedServices { get; } protected ConcurrentDictionary<Type, Lazy<object?>> CachedServices { get; }
protected CachedServiceProviderBase(IServiceProvider serviceProvider) protected CachedServiceProviderBase(IServiceProvider serviceProvider)
{ {
ServiceProvider = serviceProvider; ServiceProvider = serviceProvider;
CachedServices = new ConcurrentDictionary<Type, Lazy<object>>(); CachedServices = new ConcurrentDictionary<Type, Lazy<object?>>();
CachedServices.TryAdd(typeof(IServiceProvider), new Lazy<object>(() => ServiceProvider)); CachedServices.TryAdd(typeof(IServiceProvider), new Lazy<object?>(() => ServiceProvider));
} }
public virtual object GetService(Type serviceType) public virtual object? GetService(Type serviceType)
{ {
return CachedServices.GetOrAdd( return CachedServices.GetOrAdd(
serviceType, serviceType,
_ => new Lazy<object>(() => ServiceProvider.GetService(serviceType)) _ => new Lazy<object?>(() => ServiceProvider.GetService(serviceType))
).Value; ).Value;
} }
public T GetService<T>(T defaultValue) public T GetService<T>(T defaultValue)
{ {
return (T)GetService(typeof(T), defaultValue); return (T)GetService(typeof(T), defaultValue!);
} }
public object GetService(Type serviceType, object defaultValue) public object GetService(Type serviceType, object defaultValue)
@ -42,7 +42,7 @@ public abstract class CachedServiceProviderBase : ICachedServiceProviderBase
{ {
return CachedServices.GetOrAdd( return CachedServices.GetOrAdd(
serviceType, serviceType,
_ => new Lazy<object>(() => factory(ServiceProvider)) _ => new Lazy<object?>(() => factory(ServiceProvider))
).Value; ).Value!;
} }
} }

8
framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/ConventionalRegistrarBase.cs

@ -52,12 +52,12 @@ public abstract class ConventionalRegistrarBase : IConventionalRegistrar
} }
} }
protected virtual DependencyAttribute GetDependencyAttributeOrNull(Type type) protected virtual DependencyAttribute? GetDependencyAttributeOrNull(Type type)
{ {
return type.GetCustomAttribute<DependencyAttribute>(true); return type.GetCustomAttribute<DependencyAttribute>(true);
} }
protected virtual ServiceLifetime? GetLifeTimeOrNull(Type type, [CanBeNull] DependencyAttribute dependencyAttribute) protected virtual ServiceLifetime? GetLifeTimeOrNull(Type type, DependencyAttribute? dependencyAttribute)
{ {
return dependencyAttribute?.Lifetime ?? GetServiceLifetimeFromClassHierarchy(type) ?? GetDefaultLifeTimeOrNull(type); return dependencyAttribute?.Lifetime ?? GetServiceLifetimeFromClassHierarchy(type) ?? GetDefaultLifeTimeOrNull(type);
} }
@ -110,7 +110,7 @@ public abstract class ConventionalRegistrarBase : IConventionalRegistrar
{ {
return ServiceDescriptor.Describe( return ServiceDescriptor.Describe(
exposingServiceType, exposingServiceType,
provider => provider.GetService(redirectedType), provider => provider.GetService(redirectedType)!,
lifeTime lifeTime
); );
} }
@ -123,7 +123,7 @@ public abstract class ConventionalRegistrarBase : IConventionalRegistrar
); );
} }
protected virtual Type GetRedirectedTypeOrNull( protected virtual Type? GetRedirectedTypeOrNull(
Type implementationType, Type implementationType,
Type exposingServiceType, Type exposingServiceType,
List<Type> allExposingServiceTypes) List<Type> allExposingServiceTypes)

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

@ -24,13 +24,13 @@ public interface IAbpLazyServiceProvider : ICachedServiceProviderBase
/// This method is equivalent of the GetService method. /// This method is equivalent of the GetService method.
/// It does exists for backward compatibility. /// It does exists for backward compatibility.
/// </summary> /// </summary>
T LazyGetService<T>(); T? LazyGetService<T>();
/// <summary> /// <summary>
/// This method is equivalent of the GetService method. /// This method is equivalent of the GetService method.
/// It does exists for backward compatibility. /// It does exists for backward compatibility.
/// </summary> /// </summary>
object LazyGetService(Type serviceType); object? LazyGetService(Type serviceType);
/// <summary> /// <summary>
/// This method is equivalent of the <see cref="ICachedServiceProviderBase.GetService{T}(T)"/> method. /// This method is equivalent of the <see cref="ICachedServiceProviderBase.GetService{T}(T)"/> method.

3
framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/IObjectAccessor.cs

@ -4,6 +4,5 @@ namespace Volo.Abp.DependencyInjection;
public interface IObjectAccessor<out T> public interface IObjectAccessor<out T>
{ {
[CanBeNull] T? Value { get; }
T Value { get; }
} }

4
framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/ObjectAccessor.cs

@ -4,14 +4,14 @@ namespace Volo.Abp.DependencyInjection;
public class ObjectAccessor<T> : IObjectAccessor<T> public class ObjectAccessor<T> : IObjectAccessor<T>
{ {
public T Value { get; set; } public T? Value { get; set; }
public ObjectAccessor() public ObjectAccessor()
{ {
} }
public ObjectAccessor([CanBeNull] T obj) public ObjectAccessor(T? obj)
{ {
Value = obj; Value = obj;
} }

4
framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/RootServiceProvider.cs

@ -9,10 +9,10 @@ public class RootServiceProvider : IRootServiceProvider, ISingletonDependency
public RootServiceProvider(IObjectAccessor<IServiceProvider> objectAccessor) public RootServiceProvider(IObjectAccessor<IServiceProvider> objectAccessor)
{ {
ServiceProvider = objectAccessor.Value; ServiceProvider = objectAccessor.Value!;
} }
public virtual object GetService(Type serviceType) public virtual object? GetService(Type serviceType)
{ {
return ServiceProvider.GetService(serviceType); return ServiceProvider.GetService(serviceType);
} }

8
framework/src/Volo.Abp.Core/Volo/Abp/DisposeAction.cs

@ -37,8 +37,7 @@ public class DisposeAction<T> : IDisposable
{ {
private readonly Action<T> _action; private readonly Action<T> _action;
[CanBeNull] private readonly T? _parameter;
private readonly T _parameter;
/// <summary> /// <summary>
/// Creates a new <see cref="DisposeAction"/> object. /// Creates a new <see cref="DisposeAction"/> object.
@ -55,6 +54,9 @@ public class DisposeAction<T> : IDisposable
public void Dispose() public void Dispose()
{ {
_action(_parameter); if (_parameter != null)
{
_action(_parameter);
}
} }
} }

13
framework/src/Volo.Abp.Core/Volo/Abp/DynamicProxy/ProxyHelper.cs

@ -28,7 +28,7 @@ public static class ProxyHelper
return obj; return obj;
} }
return targetField.GetValue(obj); return targetField.GetValue(obj)!;
} }
public static Type GetUnProxiedType(object obj) public static Type GetUnProxiedType(object obj)
@ -36,15 +36,12 @@ public static class ProxyHelper
if (obj.GetType().Namespace == ProxyNamespace) if (obj.GetType().Namespace == ProxyNamespace)
{ {
var target = UnProxy(obj); var target = UnProxy(obj);
if (target != null) if (target == obj)
{ {
if (target == obj) return obj.GetType().GetTypeInfo().BaseType!;
{
return obj.GetType().GetTypeInfo().BaseType;
}
return target.GetType();
} }
return target.GetType();
} }
return obj.GetType(); return obj.GetType();

2
framework/src/Volo.Abp.Core/Volo/Abp/ExceptionHandling/IHasErrorCode.cs

@ -2,5 +2,5 @@
public interface IHasErrorCode public interface IHasErrorCode
{ {
string Code { get; } string? Code { get; }
} }

2
framework/src/Volo.Abp.Core/Volo/Abp/ExceptionHandling/IHasErrorDetails.cs

@ -2,5 +2,5 @@ namespace Volo.Abp.ExceptionHandling;
public interface IHasErrorDetails public interface IHasErrorDetails
{ {
string Details { get; } string? Details { get; }
} }

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

@ -2,5 +2,5 @@
public interface IAbpHostEnvironment public interface IAbpHostEnvironment
{ {
string EnvironmentName { get; set; } string? EnvironmentName { get; set; }
} }

3
framework/src/Volo.Abp.Core/Volo/Abp/IApplicationInfoAccessor.cs

@ -9,8 +9,7 @@ public interface IApplicationInfoAccessor
/// This is useful for systems with multiple applications, to distinguish /// This is useful for systems with multiple applications, to distinguish
/// resources of the applications located together. /// resources of the applications located together.
/// </summary> /// </summary>
[CanBeNull] string? ApplicationName { get; }
string ApplicationName { get; }
/// <summary> /// <summary>
/// A unique identifier for this application instance. /// A unique identifier for this application instance.

9
framework/src/Volo.Abp.Core/Volo/Abp/IO/FileHelper.cs

@ -36,8 +36,7 @@ public static class FileHelper
/// Returns extension without dot. /// Returns extension without dot.
/// Returns null if given <paramref name="fileNameWithExtension"></paramref> does not include dot. /// Returns null if given <paramref name="fileNameWithExtension"></paramref> does not include dot.
/// </returns> /// </returns>
[CanBeNull] public static string? GetExtension([NotNull] string fileNameWithExtension)
public static string GetExtension([NotNull] string fileNameWithExtension)
{ {
Check.NotNull(fileNameWithExtension, nameof(fileNameWithExtension)); Check.NotNull(fileNameWithExtension, nameof(fileNameWithExtension));
@ -90,7 +89,7 @@ public static class FileHelper
/// <param name="fileOptions">Indicates FileStream options. Default is Asynchronous (The file is to be used for asynchronous reading.) and SequentialScan (The file is to be accessed sequentially from beginning to end.) </param> /// <param name="fileOptions">Indicates FileStream options. Default is Asynchronous (The file is to be used for asynchronous reading.) and SequentialScan (The file is to be accessed sequentially from beginning to end.) </param>
/// <returns>A string containing all lines of the file.</returns> /// <returns>A string containing all lines of the file.</returns>
public static async Task<string[]> ReadAllLinesAsync(string path, public static async Task<string[]> ReadAllLinesAsync(string path,
Encoding encoding = null, Encoding? encoding = null,
FileMode fileMode = FileMode.Open, FileMode fileMode = FileMode.Open,
FileAccess fileAccess = FileAccess.Read, FileAccess fileAccess = FileAccess.Read,
FileShare fileShare = FileShare.Read, FileShare fileShare = FileShare.Read,
@ -114,7 +113,7 @@ public static class FileHelper
{ {
using (var reader = new StreamReader(stream, encoding)) using (var reader = new StreamReader(stream, encoding))
{ {
string line; string? line;
while ((line = await reader.ReadLineAsync()) != null) while ((line = await reader.ReadLineAsync()) != null)
{ {
lines.Add(line); lines.Add(line);
@ -134,6 +133,6 @@ public static class FileHelper
{ {
var content = await ReadAllBytesAsync(path); var content = await ReadAllBytesAsync(path);
return StringHelper.ConvertFromBytesWithoutBom(content); return StringHelper.ConvertFromBytesWithoutBom(content)!;
} }
} }

4
framework/src/Volo.Abp.Core/Volo/Abp/Localization/CultureHelper.cs

@ -7,7 +7,7 @@ namespace Volo.Abp.Localization;
public static class CultureHelper public static class CultureHelper
{ {
public static IDisposable Use([NotNull] string culture, string uiCulture = null) public static IDisposable Use([NotNull] string culture, string? uiCulture = null)
{ {
Check.NotNull(culture, nameof(culture)); Check.NotNull(culture, nameof(culture));
@ -19,7 +19,7 @@ public static class CultureHelper
); );
} }
public static IDisposable Use([NotNull] CultureInfo culture, CultureInfo uiCulture = null) public static IDisposable Use([NotNull] CultureInfo culture, CultureInfo? uiCulture = null)
{ {
Check.NotNull(culture, nameof(culture)); Check.NotNull(culture, nameof(culture));

6
framework/src/Volo.Abp.Core/Volo/Abp/Logging/AbpInitLogEntry.cs

@ -9,11 +9,11 @@ public class AbpInitLogEntry
public EventId EventId { get; set; } public EventId EventId { get; set; }
public object State { get; set; } public object State { get; set; } = default!;
public Exception Exception { get; set; } public Exception? Exception { get; set; }
public Func<object, Exception, string> Formatter { get; set; } public Func<object, Exception?, string> Formatter { get; set; } = default!;
public string Message => Formatter(State, Exception); public string Message => Formatter(State, Exception);
} }

6
framework/src/Volo.Abp.Core/Volo/Abp/Logging/DefaultInitLogger.cs

@ -13,13 +13,13 @@ public class DefaultInitLogger<T> : IInitLogger<T>
Entries = new List<AbpInitLogEntry>(); Entries = new List<AbpInitLogEntry>();
} }
public virtual void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter) public virtual void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func<TState, Exception?, string> formatter)
{ {
Entries.Add(new AbpInitLogEntry Entries.Add(new AbpInitLogEntry
{ {
LogLevel = logLevel, LogLevel = logLevel,
EventId = eventId, EventId = eventId,
State = state, State = state!,
Exception = exception, Exception = exception,
Formatter = (s, e) => formatter((TState)s, e), Formatter = (s, e) => formatter((TState)s, e),
}); });
@ -30,7 +30,7 @@ public class DefaultInitLogger<T> : IInitLogger<T>
return logLevel != LogLevel.None; return logLevel != LogLevel.None;
} }
public virtual IDisposable BeginScope<TState>(TState state) public virtual IDisposable BeginScope<TState>(TState state) where TState : notnull
{ {
return NullDisposable.Instance; return NullDisposable.Instance;
} }

2
framework/src/Volo.Abp.Core/Volo/Abp/Modularity/AbpModule.cs

@ -29,7 +29,7 @@ public abstract class AbpModule :
internal set => _serviceConfigurationContext = value; internal set => _serviceConfigurationContext = value;
} }
private ServiceConfigurationContext _serviceConfigurationContext; private ServiceConfigurationContext? _serviceConfigurationContext;
public virtual Task PreConfigureServicesAsync(ServiceConfigurationContext context) public virtual Task PreConfigureServicesAsync(ServiceConfigurationContext context)
{ {

2
framework/src/Volo.Abp.Core/Volo/Abp/Modularity/DependsOnAttribute.cs

@ -12,7 +12,7 @@ public class DependsOnAttribute : Attribute, IDependedTypesProvider
[NotNull] [NotNull]
public Type[] DependedTypes { get; } public Type[] DependedTypes { get; }
public DependsOnAttribute(params Type[] dependedTypes) public DependsOnAttribute(params Type[]? dependedTypes)
{ {
DependedTypes = dependedTypes ?? new Type[0]; DependedTypes = dependedTypes ?? new Type[0];
} }

2
framework/src/Volo.Abp.Core/Volo/Abp/Modularity/ModuleLoader.cs

@ -85,7 +85,7 @@ public class ModuleLoader : IModuleLoader
protected virtual IAbpModule CreateAndRegisterModule(IServiceCollection services, Type moduleType) protected virtual IAbpModule CreateAndRegisterModule(IServiceCollection services, Type moduleType)
{ {
var module = (IAbpModule)Activator.CreateInstance(moduleType); var module = (IAbpModule)Activator.CreateInstance(moduleType)!;
services.AddSingleton(moduleType, module); services.AddSingleton(moduleType, module);
return module; return module;
} }

2
framework/src/Volo.Abp.Core/Volo/Abp/Modularity/PlugIns/FilePlugInSource.cs

@ -8,7 +8,7 @@ public class FilePlugInSource : IPlugInSource
{ {
public string[] FilePaths { get; } public string[] FilePaths { get; }
public FilePlugInSource(params string[] filePaths) public FilePlugInSource(params string[]? filePaths)
{ {
FilePaths = filePaths ?? new string[0]; FilePaths = filePaths ?? new string[0];
} }

2
framework/src/Volo.Abp.Core/Volo/Abp/Modularity/PlugIns/FolderPlugInSource.cs

@ -15,7 +15,7 @@ public class FolderPlugInSource : IPlugInSource
public SearchOption SearchOption { get; set; } public SearchOption SearchOption { get; set; }
public Func<string, bool> Filter { get; set; } public Func<string, bool>? Filter { get; set; }
public FolderPlugInSource( public FolderPlugInSource(
[NotNull] string folder, [NotNull] string folder,

2
framework/src/Volo.Abp.Core/Volo/Abp/Modularity/PlugIns/TypePlugInSource.cs

@ -7,7 +7,7 @@ public class TypePlugInSource : IPlugInSource
{ {
private readonly Type[] _moduleTypes; private readonly Type[] _moduleTypes;
public TypePlugInSource(params Type[] moduleTypes) public TypePlugInSource(params Type[]? moduleTypes)
{ {
_moduleTypes = moduleTypes ?? new Type[0]; _moduleTypes = moduleTypes ?? new Type[0];
} }

6
framework/src/Volo.Abp.Core/Volo/Abp/Modularity/ServiceConfigurationContext.cs

@ -8,7 +8,7 @@ public class ServiceConfigurationContext
{ {
public IServiceCollection Services { get; } public IServiceCollection Services { get; }
public IDictionary<string, object> Items { get; } public IDictionary<string, object?> Items { get; }
/// <summary> /// <summary>
/// Gets/sets arbitrary named objects those can be stored during /// Gets/sets arbitrary named objects those can be stored during
@ -19,7 +19,7 @@ public class ServiceConfigurationContext
/// </summary> /// </summary>
/// <param name="key"></param> /// <param name="key"></param>
/// <returns></returns> /// <returns></returns>
public object this[string key] { public object? this[string key] {
get => Items.GetOrDefault(key); get => Items.GetOrDefault(key);
set => Items[key] = value; set => Items[key] = value;
} }
@ -27,6 +27,6 @@ public class ServiceConfigurationContext
public ServiceConfigurationContext([NotNull] IServiceCollection services) public ServiceConfigurationContext([NotNull] IServiceCollection services)
{ {
Services = Check.NotNull(services, nameof(services)); Services = Check.NotNull(services, nameof(services));
Items = new Dictionary<string, object>(); Items = new Dictionary<string, object?>();
} }
} }

4
framework/src/Volo.Abp.Core/Volo/Abp/NameValue.cs

@ -29,12 +29,12 @@ public class NameValue<T>
/// <summary> /// <summary>
/// Name. /// Name.
/// </summary> /// </summary>
public string Name { get; set; } public string Name { get; set; } = default!;
/// <summary> /// <summary>
/// Value. /// Value.
/// </summary> /// </summary>
public T Value { get; set; } public T Value { get; set; } = default!;
public NameValue() public NameValue()
{ {

10
framework/src/Volo.Abp.Core/Volo/Abp/ObjectHelper.cs

@ -9,8 +9,8 @@ namespace Volo.Abp;
public static class ObjectHelper public static class ObjectHelper
{ {
private static readonly ConcurrentDictionary<string, PropertyInfo> CachedObjectProperties = private static readonly ConcurrentDictionary<string, PropertyInfo?> CachedObjectProperties =
new ConcurrentDictionary<string, PropertyInfo>(); new ConcurrentDictionary<string, PropertyInfo?>();
public static void TrySetProperty<TObject, TValue>( public static void TrySetProperty<TObject, TValue>(
TObject obj, TObject obj,
@ -25,9 +25,9 @@ public static class ObjectHelper
TObject obj, TObject obj,
Expression<Func<TObject, TValue>> propertySelector, Expression<Func<TObject, TValue>> propertySelector,
Func<TObject, TValue> valueFactory, Func<TObject, TValue> valueFactory,
params Type[] ignoreAttributeTypes) params Type[]? ignoreAttributeTypes)
{ {
var cacheKey = $"{obj.GetType().FullName}-" + var cacheKey = $"{obj?.GetType().FullName}-" +
$"{propertySelector}-" + $"{propertySelector}-" +
$"{(ignoreAttributeTypes != null ? "-" + string.Join("-", ignoreAttributeTypes.Select(x => x.FullName)) : "")}"; $"{(ignoreAttributeTypes != null ? "-" + string.Join("-", ignoreAttributeTypes.Select(x => x.FullName)) : "")}";
@ -40,7 +40,7 @@ public static class ObjectHelper
var memberExpression = propertySelector.Body.As<MemberExpression>(); var memberExpression = propertySelector.Body.As<MemberExpression>();
var propertyInfo = obj.GetType().GetProperties().FirstOrDefault(x => var propertyInfo = obj?.GetType().GetProperties().FirstOrDefault(x =>
x.Name == memberExpression.Member.Name && x.Name == memberExpression.Member.Name &&
x.GetSetMethod(true) != null); x.GetSetMethod(true) != null);

4
framework/src/Volo.Abp.Core/Volo/Abp/Options/AbpOptionsFactory.cs

@ -9,7 +9,7 @@ public class AbpOptionsFactory<TOptions> : IOptionsFactory<TOptions> where TOpti
{ {
private readonly IEnumerable<IConfigureOptions<TOptions>> _setups; private readonly IEnumerable<IConfigureOptions<TOptions>> _setups;
private readonly IEnumerable<IPostConfigureOptions<TOptions>> _postConfigures; private readonly IEnumerable<IPostConfigureOptions<TOptions>> _postConfigures;
private readonly IEnumerable<IValidateOptions<TOptions>> _validations; private readonly IEnumerable<IValidateOptions<TOptions>>? _validations;
public AbpOptionsFactory( public AbpOptionsFactory(
IEnumerable<IConfigureOptions<TOptions>> setups, IEnumerable<IConfigureOptions<TOptions>> setups,
@ -22,7 +22,7 @@ public class AbpOptionsFactory<TOptions> : IOptionsFactory<TOptions> where TOpti
public AbpOptionsFactory( public AbpOptionsFactory(
IEnumerable<IConfigureOptions<TOptions>> setups, IEnumerable<IConfigureOptions<TOptions>> setups,
IEnumerable<IPostConfigureOptions<TOptions>> postConfigures, IEnumerable<IPostConfigureOptions<TOptions>> postConfigures,
IEnumerable<IValidateOptions<TOptions>> validations) IEnumerable<IValidateOptions<TOptions>>? validations)
{ {
_setups = setups; _setups = setups;
_postConfigures = postConfigures; _postConfigures = postConfigures;

2
framework/src/Volo.Abp.Core/Volo/Abp/Reflection/AssemblyHelper.cs

@ -31,7 +31,7 @@ internal static class AssemblyHelper
} }
catch (ReflectionTypeLoadException ex) catch (ReflectionTypeLoadException ex)
{ {
return ex.Types; return ex.Types!;
} }
} }
} }

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save