L
+@inject ICurrentUser CurrentUser
+@section styles {
+
+}
+@section scripts {
+
+}
+
+
+
+
+
+
+
+
+
+
+
Search & Display Images
+
+
+
+
+
+
+
+
+
+
+```
+
+Then, open the `index.js` file and replace it with the following content:
+
+```js
+$(function () {
+
+ $("#upload-image").submit(function (e) {
+ e.preventDefault();
+
+ var file = document.getElementById("formFile").files[0];
+ var formData = new FormData();
+ formData.append("file", file);
+
+ $.ajax(
+ {
+ url: "/api/image/upload",
+ data: formData,
+ processData: false,
+ contentType: false,
+ type: "POST",
+ success: function (data) {
+ abp.message.success("Image saved successfully!");
+ },
+ error: function (err) {
+ abp.message.error("An error occured while saving the image.");
+ }
+ }
+ );
+ });
+
+ $("#search-image").submit(function (e) {
+ e.preventDefault();
+
+ var imgResult = $("#image-result");
+ imgResult.removeClass("d-none");
+
+ imgResult.html("Loading...
");
+
+ var fileName = $("#img-search-input").val();
+
+ imageManipulationDemo.controllers.image.getImage(fileName)
+ .then(function (imageFile) {
+ var src = "data:image/png;base64," + imageFile;
+ var img = " ";
+
+ imgResult.html(img);
+ })
+ .catch(function (err) {
+ imgResult.html("Could not find the image...
");
+ });
+ });
+});
+```
+
+Now, we can run the application and see the Image Manipulation System in action:
+
+
+
+The results are impressive for the example above:
+
+* The original image was 12 KB and now the compressed & resized image has been reduced to 8 KB.
+* The original image was 225x225 and now resized as 200x200.
+
+## Conclusion
+
+In this article, I have shown you how to compress and/or resize images with ABP Framework's Image Manipulation System by just defining some attributes to the top of the controller actions.
+
+Also, I have shown that you can use the BLOB Storing System to store file contents and compress/resize images before saving them into BLOB Storages thanks to the image resizers/compressors provided by ABP Framework.
+
+## See Also
+
+* [BLOB Storing](https://docs.abp.io/en/abp/latest/Blob-Storing)
+* [Image Manipulation](https://docs.abp.io/en/abp/7.3/Image-Manipulation#iimageresizer)
diff --git a/docs/en/Community-Articles/2023-07-03-Image-Compression-And-Resize/image-manipulation.gif b/docs/en/Community-Articles/2023-07-03-Image-Compression-And-Resize/image-manipulation.gif
new file mode 100644
index 0000000000..d8b2a10c16
Binary files /dev/null and b/docs/en/Community-Articles/2023-07-03-Image-Compression-And-Resize/image-manipulation.gif differ
diff --git a/docs/en/Community-Articles/2023-07-03-Image-Compression-And-Resize/image-upload-ui.png b/docs/en/Community-Articles/2023-07-03-Image-Compression-And-Resize/image-upload-ui.png
new file mode 100644
index 0000000000..d5fab5a945
Binary files /dev/null and b/docs/en/Community-Articles/2023-07-03-Image-Compression-And-Resize/image-upload-ui.png differ
diff --git a/docs/en/Integration-Services.md b/docs/en/Integration-Services.md
index e788c348f7..98e3e593e5 100644
--- a/docs/en/Integration-Services.md
+++ b/docs/en/Integration-Services.md
@@ -34,11 +34,47 @@ public interface IProductAppService : IApplicationService
That's all. From now, ABP will handle your application service as integration service and implement the followings by convention:
-* If you are using the [Auto API Controllers](API/Auto-API-Controllers.md) feature in your application, the URL prefix will be `/integration-api` instead of `/api` for your integration services. Thus, you can distinguish internal and external service communications and take additional actions, such as preventing REST API calls for integration services out of API Gateway.
-* Audit logging is disabled by default for the integration services. See the next section if you want to enable it.
+* That service is **not exposed** by default, unless you explicitly set `ExposeIntegrationServices` options (see the *Exposing Integration Services* section).
+* If you are using the [Auto API Controllers](API/Auto-API-Controllers.md) feature in your application, the **URL prefix** will be `/integration-api` instead of `/api` for your integration services. Thus, you can distinguish internal and external service communications and take additional actions, such as preventing REST API calls for integration services out of API Gateway.
+* **Audit logging** is disabled by default for the integration services. See the next section if you want to enable it.
+
+## Marking an MVC Controller as Integration Service
+
+In addition to application services, you can mark a regular MVC Controller as integration service, using the same `IntegrationService` attribute, or inheriting an interface that has the `IntegrationService` attribute.
+
+**Example:**
+
+````csharp
+[IntegrationService] // Mark as integration service
+[Route("integration-api/products")]
+public class ProductController : AbpControllerBase
+{
+ //...
+}
+````
+
+When you use the `IntegrationService` attribute, ABP will handle your controller as integration service and implement the followings by convention:
+
+* That controller is **not exposed** to clients by default, unless you explicitly set `ExposeIntegrationServices` options (see the *Exposing Integration Services* section).
+* **Audit logging** is disabled by default for controller. See the next section if you want to enable it.
## Configuration
+### Exposing Integration Services
+
+Integration services and controllers are not exposed by default for security reasons. They typically don't require authorization, so you should **carefully and explicitly** allow them to be visible and usable to client applications.
+
+To expose integration services and controllers, set `AbpAspNetCoreMvcOptions.ExposeIntegrationServices` to `true` in the `ConfigureServices` method of your [module class](Module-Development-Basics.md):
+
+````csharp
+Configure(options =>
+{
+ options.ExposeIntegrationServices = true;
+});
+````
+
+> Hiding integration services is useful when you are building reusable application modules, where they may be used in a monolith application or in a microservice system. In a monolith application, integration services don't need to be exposed outside since the modules may in-process communicate with each other. On the other hand, if you build a microservice solution and use that module as a service, it will be proper to expose the integration services, so other microservices can consume them remotely inside your private network (or Kubernetes cluster). In that case, be careful to not accidently expose the integration services out of your private network. Configuring your API Gateway so that it blocks requests to `integration-api` prefixed URLs from outside of your network will be a good option.
+
### Enabling/Disabling the Audit Logging
Audit Logging is disabled by default for integration services but it can be enabled by configuring the `AbpAuditingOptions` [options class](Options.md) in the `ConfigureServices` method of your [module class](Module-Development-Basics.md):
diff --git a/docs/en/Migration-Guides/docs/en/Migration-Guides/Abp-7_4.md b/docs/en/Migration-Guides/docs/en/Migration-Guides/Abp-7_4.md
new file mode 100644
index 0000000000..5ec8eb6c65
--- /dev/null
+++ b/docs/en/Migration-Guides/docs/en/Migration-Guides/Abp-7_4.md
@@ -0,0 +1,8 @@
+# ABP Version 7.4 Migration Guide
+
+This document is a guide for upgrading ABP v7.3 solutions to ABP v7.4. There are a few changes in this version that may affect your applications, please read it carefully and apply the necessary changes to your application.
+
+## TemplateDefinition
+
+The `LocalizationResource(Type)` of `TemplateDefinition` class is changed to `LocalizationResourceName(string)`.
+
diff --git a/docs/en/Module-Development-Basics.md b/docs/en/Module-Development-Basics.md
index dfce0bf4b2..1fdd09f8b2 100644
--- a/docs/en/Module-Development-Basics.md
+++ b/docs/en/Module-Development-Basics.md
@@ -147,7 +147,7 @@ Lastly, you can override ``OnApplicationShutdown`` method if you want to execute
## Module Dependencies
-In a modular application, it's not unusual for one module to depend upon another module(s). An Abp module must declare ``[DependsOn]`` attribute if it does have a dependency upon another module, as shown below:
+In a modular application, it's not unusual for one module to depend upon another module(s). An ABP module must declare a ``[DependsOn]`` attribute if it does have a dependency upon another module, as shown below:
````C#
[DependsOn(typeof(AbpAspNetCoreMvcModule))]
@@ -162,6 +162,27 @@ You can use multiple ``DependsOn`` attribute or pass multiple module types to a
A depended module may depend on another module, but you only need to define your direct dependencies. ABP investigates the dependency graph for the application at startup and initializes/shutdowns modules in the correct order.
+## Additional Module Assemblies
+
+ABP automatically registers all the services of your module to the [dependency injection](Dependency-Injection.md) system. It finds the service types by scanning types in the assembly that defines your module class. That assembly is considered as the main assembly of your module.
+
+Typically, every assembly contains a separate module class definition. Then modules depend on each other using the `DependsOn` attribute as explained in the previous section. However, in some rare cases, your module may consist of multiple assemblies, and only one of them defines a module class, and you want to make the other assemblies parts of your module. In that case, you can use the `AdditionalAssembly` attribute as shown below:
+
+````csharp
+[DependsOn(...)] // Your module dependencies as you normally do
+[AdditionalAssembly(typeof(BlogService))] // A type in the target assembly
+public class BlogModule
+{
+ //...
+}
+````
+
+In this example, we assume that the `BlogService` class is inside one assembly (`csproj`) and the `BlogModule` class is inside another assembly (`csproj`). With the `AdditionalAssembly` definition, ABP will load the assembly containing the `BlogService` class as a part of the blog module.
+
+Notice that `BlogService` is only an arbitrary selected type in the target assembly. It is just used to indicate the related assembly. You could use any type in the assembly.
+
+> WARNING: If you need to use the `AdditionalAssembly`, be sure that you don't design your system in a wrong way. With this example above, the `BlogService` class' assembly should normally have its own module class and the `BlogModule` should depend on it using the `DependsOn` attribute. Do not use the `AdditionalAssembly` attribute when you can already use the `DependsOn` attribute.
+
## Framework Modules vs Application Modules
There are **two types of modules.** They don't have any structural difference but categorized by functionality and purpose:
diff --git a/docs/en/Module-Entity-Extensions.md b/docs/en/Module-Entity-Extensions.md
index 47436a7dd9..93c79120cd 100644
--- a/docs/en/Module-Entity-Extensions.md
+++ b/docs/en/Module-Entity-Extensions.md
@@ -255,6 +255,20 @@ property =>
Use `property.UI.OnCreateForm` and `property.UI.OnEditForm` to control forms too. If a property is required, but not added to the create form, you definitely get a validation exception, so use this option carefully. But a required property may not be in the edit form if that's your requirement.
+### UI Order
+
+When you define a property, it appears on the data table, create and edit forms on the related UI page. However, you can control its order. Example:
+
+````csharp
+property =>
+{
+ property.UI.Order = 1;
+ //...other configurations
+}
+````
+
+Use `property.UI.OnCreateForm` and `property.UI.OnEditForm` to control forms too. If a property is required, but not added to the create form, you definitely get a validation exception, so use this option carefully. But a required property may not be in the edit form if that's your requirement.
+
### HTTP API Availability
Even if you disable a property on UI, it can be still available through the HTTP API. By default, a property is available on all APIs.
diff --git a/framework/src/Volo.Abp.ApiVersioning.Abstractions/Volo.Abp.ApiVersioning.Abstractions.csproj b/framework/src/Volo.Abp.ApiVersioning.Abstractions/Volo.Abp.ApiVersioning.Abstractions.csproj
index 038e852f21..2924448609 100644
--- a/framework/src/Volo.Abp.ApiVersioning.Abstractions/Volo.Abp.ApiVersioning.Abstractions.csproj
+++ b/framework/src/Volo.Abp.ApiVersioning.Abstractions/Volo.Abp.ApiVersioning.Abstractions.csproj
@@ -5,6 +5,8 @@
netstandard2.0;netstandard2.1;net7.0
+ enable
+ Nullable
Volo.Abp.ApiVersioning.Abstractions
Volo.Abp.ApiVersioning.Abstractions
$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;
diff --git a/framework/src/Volo.Abp.ApiVersioning.Abstractions/Volo/Abp/ApiVersioning/IRequestedApiVersion.cs b/framework/src/Volo.Abp.ApiVersioning.Abstractions/Volo/Abp/ApiVersioning/IRequestedApiVersion.cs
index 96c2ef33cd..428f8bb6c0 100644
--- a/framework/src/Volo.Abp.ApiVersioning.Abstractions/Volo/Abp/ApiVersioning/IRequestedApiVersion.cs
+++ b/framework/src/Volo.Abp.ApiVersioning.Abstractions/Volo/Abp/ApiVersioning/IRequestedApiVersion.cs
@@ -2,5 +2,5 @@
public interface IRequestedApiVersion
{
- string Current { get; }
+ string? Current { get; }
}
diff --git a/framework/src/Volo.Abp.ApiVersioning.Abstractions/Volo/Abp/ApiVersioning/NullRequestedApiVersion.cs b/framework/src/Volo.Abp.ApiVersioning.Abstractions/Volo/Abp/ApiVersioning/NullRequestedApiVersion.cs
index 0589c662ef..6099283cc4 100644
--- a/framework/src/Volo.Abp.ApiVersioning.Abstractions/Volo/Abp/ApiVersioning/NullRequestedApiVersion.cs
+++ b/framework/src/Volo.Abp.ApiVersioning.Abstractions/Volo/Abp/ApiVersioning/NullRequestedApiVersion.cs
@@ -4,7 +4,7 @@ public class NullRequestedApiVersion : IRequestedApiVersion
{
public static NullRequestedApiVersion Instance = new NullRequestedApiVersion();
- public string Current => null;
+ public string? Current => null;
private NullRequestedApiVersion()
{
diff --git a/framework/src/Volo.Abp.AspNetCore.Authentication.JwtBearer/Volo.Abp.AspNetCore.Authentication.JwtBearer.csproj b/framework/src/Volo.Abp.AspNetCore.Authentication.JwtBearer/Volo.Abp.AspNetCore.Authentication.JwtBearer.csproj
index bfe8b1d37b..6deeaac7e3 100644
--- a/framework/src/Volo.Abp.AspNetCore.Authentication.JwtBearer/Volo.Abp.AspNetCore.Authentication.JwtBearer.csproj
+++ b/framework/src/Volo.Abp.AspNetCore.Authentication.JwtBearer/Volo.Abp.AspNetCore.Authentication.JwtBearer.csproj
@@ -5,6 +5,8 @@
net7.0
+ enable
+ Nullable
Volo.Abp.AspNetCore.Authentication.JwtBearer
Volo.Abp.AspNetCore.Authentication.JwtBearer
$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;
diff --git a/framework/src/Volo.Abp.AspNetCore.Authentication.OAuth/Volo.Abp.AspNetCore.Authentication.OAuth.csproj b/framework/src/Volo.Abp.AspNetCore.Authentication.OAuth/Volo.Abp.AspNetCore.Authentication.OAuth.csproj
index 562e559273..f8efe3c11c 100644
--- a/framework/src/Volo.Abp.AspNetCore.Authentication.OAuth/Volo.Abp.AspNetCore.Authentication.OAuth.csproj
+++ b/framework/src/Volo.Abp.AspNetCore.Authentication.OAuth/Volo.Abp.AspNetCore.Authentication.OAuth.csproj
@@ -5,6 +5,8 @@
net7.0
+ enable
+ Nullable
Volo.Abp.AspNetCore.Authentication.OAuth
Volo.Abp.AspNetCore.Authentication.OAuth
$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;
diff --git a/framework/src/Volo.Abp.AspNetCore.Authentication.OAuth/Volo/Abp/AspNetCore/Authentication/OAuth/Claims/MultipleClaimAction.cs b/framework/src/Volo.Abp.AspNetCore.Authentication.OAuth/Volo/Abp/AspNetCore/Authentication/OAuth/Claims/MultipleClaimAction.cs
index 1910af63d5..e058303572 100644
--- a/framework/src/Volo.Abp.AspNetCore.Authentication.OAuth/Volo/Abp/AspNetCore/Authentication/OAuth/Claims/MultipleClaimAction.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Authentication.OAuth/Volo/Abp/AspNetCore/Authentication/OAuth/Claims/MultipleClaimAction.cs
@@ -29,7 +29,7 @@ public class MultipleClaimAction : ClaimAction
switch (prop.ValueKind)
{
case JsonValueKind.String:
- claim = new Claim(ClaimType, prop.GetString(), ValueType, issuer);
+ claim = new Claim(ClaimType, prop.GetString()!, ValueType, issuer);
if (!identity.Claims.Any(c => c.Type == claim.Type && c.Value == claim.Value))
{
identity.AddClaim(claim);
@@ -38,7 +38,7 @@ public class MultipleClaimAction : ClaimAction
case JsonValueKind.Array:
foreach (var arramItem in prop.EnumerateArray())
{
- claim = new Claim(ClaimType, arramItem.GetString(), ValueType, issuer);
+ claim = new Claim(ClaimType, arramItem.GetString()!, ValueType, issuer);
if (!identity.Claims.Any(c => c.Type == claim.Type && c.Value == claim.Value))
{
identity.AddClaim(claim);
diff --git a/framework/src/Volo.Abp.AspNetCore.Authentication.OpenIdConnect/Microsoft/Extensions/DependencyInjection/AbpOpenIdConnectExtensions.cs b/framework/src/Volo.Abp.AspNetCore.Authentication.OpenIdConnect/Microsoft/Extensions/DependencyInjection/AbpOpenIdConnectExtensions.cs
index 2a2d0a712d..7d2c1fe6d6 100644
--- a/framework/src/Volo.Abp.AspNetCore.Authentication.OpenIdConnect/Microsoft/Extensions/DependencyInjection/AbpOpenIdConnectExtensions.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Authentication.OpenIdConnect/Microsoft/Extensions/DependencyInjection/AbpOpenIdConnectExtensions.cs
@@ -28,8 +28,6 @@ public static class AbpOpenIdConnectExtensions
{
options.ClaimActions.MapAbpClaimTypes();
- configureOptions?.Invoke(options);
-
options.Events ??= new OpenIdConnectEvents();
var authorizationCodeReceived = options.Events.OnAuthorizationCodeReceived ?? (_ => Task.CompletedTask);
@@ -39,16 +37,7 @@ public static class AbpOpenIdConnectExtensions
return authorizationCodeReceived.Invoke(receivedContext);
};
- options.Events.OnRemoteFailure = remoteFailureContext =>
- {
- if (remoteFailureContext.Failure is OpenIdConnectProtocolException &&
- remoteFailureContext.Failure.Message.Contains("access_denied"))
- {
- remoteFailureContext.HandleResponse();
- remoteFailureContext.Response.Redirect($"{remoteFailureContext.Request.PathBase}/");
- }
- return Task.CompletedTask;
- };
+ options.AccessDeniedPath = "/";
options.Events.OnTokenValidated = async (context) =>
{
@@ -63,6 +52,8 @@ public static class AbpOpenIdConnectExtensions
logger?.LogException(ex);
}
};
+
+ configureOptions?.Invoke(options);
});
}
diff --git a/framework/src/Volo.Abp.AspNetCore.Authentication.OpenIdConnect/Volo.Abp.AspNetCore.Authentication.OpenIdConnect.csproj b/framework/src/Volo.Abp.AspNetCore.Authentication.OpenIdConnect/Volo.Abp.AspNetCore.Authentication.OpenIdConnect.csproj
index 9f1051fbd5..9fa50a203f 100644
--- a/framework/src/Volo.Abp.AspNetCore.Authentication.OpenIdConnect/Volo.Abp.AspNetCore.Authentication.OpenIdConnect.csproj
+++ b/framework/src/Volo.Abp.AspNetCore.Authentication.OpenIdConnect/Volo.Abp.AspNetCore.Authentication.OpenIdConnect.csproj
@@ -5,6 +5,8 @@
net7.0
+ enable
+ Nullable
diff --git a/framework/src/Volo.Abp.AspNetCore.Components/Volo/Abp/AspNetCore/Components/AbpComponentBase.cs b/framework/src/Volo.Abp.AspNetCore.Components/Volo/Abp/AspNetCore/Components/AbpComponentBase.cs
index dc1923f180..47a0d570bf 100644
--- a/framework/src/Volo.Abp.AspNetCore.Components/Volo/Abp/AspNetCore/Components/AbpComponentBase.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Components/Volo/Abp/AspNetCore/Components/AbpComponentBase.cs
@@ -168,6 +168,11 @@ public abstract class AbpComponentBase : OwningComponentBase
protected virtual async Task HandleErrorAsync(Exception exception)
{
+ if (IsDisposed)
+ {
+ return;
+ }
+
Logger.LogException(exception);
await InvokeAsync(async () =>
{
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Controllers/AbpAspNetCoreMvcDaprEventsController.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Controllers/AbpAspNetCoreMvcDaprEventsController.cs
index da0dad6a70..b1d5bac7fb 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Controllers/AbpAspNetCoreMvcDaprEventsController.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Controllers/AbpAspNetCoreMvcDaprEventsController.cs
@@ -1,4 +1,5 @@
using System;
+using System.Linq;
using System.Text.Json;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
@@ -21,7 +22,6 @@ public class AbpAspNetCoreMvcDaprEventsController : AbpController
var daprSerializer = HttpContext.RequestServices.GetRequiredService();
var body = (await JsonDocument.ParseAsync(HttpContext.Request.Body));
- var id = body.RootElement.GetProperty("id").GetString();
var pubSubName = body.RootElement.GetProperty("pubsubname").GetString();
var topic = body.RootElement.GetProperty("topic").GetString();
var data = body.RootElement.GetProperty("data").GetRawText();
@@ -32,8 +32,31 @@ public class AbpAspNetCoreMvcDaprEventsController : AbpController
}
var distributedEventBus = HttpContext.RequestServices.GetRequiredService();
- var eventData = daprSerializer.Deserialize(data, distributedEventBus.GetEventType(topic));
- await distributedEventBus.TriggerHandlersAsync(id, distributedEventBus.GetEventType(topic), eventData);
+
+ if (IsAbpDaprEventData(data))
+ {
+ var daprEventData = daprSerializer.Deserialize(data, typeof(AbpDaprEventData)).As();
+ var eventData = daprSerializer.Deserialize(daprEventData.JsonData, distributedEventBus.GetEventType(daprEventData.Topic));
+ await distributedEventBus.TriggerHandlersAsync(distributedEventBus.GetEventType(daprEventData.Topic), eventData, daprEventData.MessageId, daprEventData.CorrelationId);
+ }
+ else
+ {
+ var eventData = daprSerializer.Deserialize(data, distributedEventBus.GetEventType(topic));
+ await distributedEventBus.TriggerHandlersAsync(distributedEventBus.GetEventType(topic), eventData);
+ }
+
return Ok();
}
+
+ protected virtual bool IsAbpDaprEventData(string data)
+ {
+ var document = JsonDocument.Parse(data);
+ var objects = document.RootElement.EnumerateObject().ToList();
+ return objects.Count == 5 &&
+ objects.Any(x => x.Name.Equals("PubSubName", StringComparison.CurrentCultureIgnoreCase)) &&
+ objects.Any(x => x.Name.Equals("Topic", StringComparison.CurrentCultureIgnoreCase)) &&
+ objects.Any(x => x.Name.Equals("MessageId", StringComparison.CurrentCultureIgnoreCase)) &&
+ objects.Any(x => x.Name.Equals("JsonData", StringComparison.CurrentCultureIgnoreCase)) &&
+ objects.Any(x => x.Name.Equals("CorrelationId", StringComparison.CurrentCultureIgnoreCase));
+ }
}
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs
index e22fef4236..c9b5984843 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs
@@ -227,18 +227,16 @@ public class AbpAspNetCoreMvcModule : AbpModule
return;
}
- //Plugin modules
- var moduleAssemblies = context
- .ServiceProvider
- .GetRequiredService()
+ var moduleContainer = context.ServiceProvider.GetRequiredService();
+
+ var plugInModuleAssemblies = moduleContainer
.Modules
.Where(m => m.IsLoadedAsPlugIn)
- .Select(m => m.Type.Assembly)
+ .SelectMany(m => m.AllAssemblies)
.Distinct();
- AddToApplicationParts(partManager, moduleAssemblies);
+ AddToApplicationParts(partManager, plugInModuleAssemblies);
- //Controllers for application services
var controllerAssemblies = context
.ServiceProvider
.GetRequiredService>()
@@ -249,6 +247,13 @@ public class AbpAspNetCoreMvcModule : AbpModule
.Distinct();
AddToApplicationParts(partManager, controllerAssemblies);
+
+ var additionalAssemblies = moduleContainer
+ .Modules
+ .SelectMany(m => m.GetAdditionalAssemblies())
+ .Distinct();
+
+ AddToApplicationParts(partManager, additionalAssemblies);
}
private static void AddToApplicationParts(ApplicationPartManager partManager, IEnumerable moduleAssemblies)
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcOptions.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcOptions.cs
index 1cd4b88fb8..56acc2f745 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcOptions.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcOptions.cs
@@ -14,6 +14,8 @@ public class AbpAspNetCoreMvcOptions
public HashSet ControllersToRemove { get; }
+ public bool ExposeIntegrationServices { get; set; } = false;
+
public bool AutoModelValidation { get; set; }
public bool EnableRazorRuntimeCompilationOnDevelopment { get; set; }
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationPartSorter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationPartSorter.cs
index 9664a2005e..dc39ef5f53 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationPartSorter.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationPartSorter.cs
@@ -125,7 +125,7 @@ public static class ApplicationPartSorter
var moduleDependedAssemblies = moduleDescriptor
.Dependencies
- .Select(d => d.Assembly)
+ .SelectMany(d => d.AllAssemblies)
.ToArray();
return partManager.ApplicationParts
@@ -161,6 +161,6 @@ public static class ApplicationPartSorter
{
return moduleContainer
.Modules
- .FirstOrDefault(m => m.Assembly == assembly);
+ .FirstOrDefault(m => m.AllAssemblies.Contains(assembly));
}
}
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Conventions/AbpServiceConvention.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Conventions/AbpServiceConvention.cs
index 933f325975..19479f552d 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Conventions/AbpServiceConvention.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Conventions/AbpServiceConvention.cs
@@ -45,6 +45,7 @@ public class AbpServiceConvention : IAbpServiceConvention, ITransientDependency
protected virtual void ApplyForControllers(ApplicationModel application)
{
RemoveDuplicateControllers(application);
+ RemoveIntegrationControllersIfNotExposed(application);
foreach (var controller in GetControllers(application))
{
@@ -72,6 +73,20 @@ public class AbpServiceConvention : IAbpServiceConvention, ITransientDependency
}
}
+ protected virtual void RemoveIntegrationControllersIfNotExposed(ApplicationModel application)
+ {
+ if (Options.ExposeIntegrationServices)
+ {
+ return;
+ }
+
+ var integrationControllers = GetControllers(application)
+ .Where(c => IntegrationServiceAttribute.IsDefinedOrInherited(c.ControllerType))
+ .ToArray();
+
+ application.Controllers.RemoveAll(integrationControllers);
+ }
+
protected virtual IList GetControllers(ApplicationModel application)
{
return application.Controllers;
diff --git a/framework/src/Volo.Abp.AspNetCore.TestBase/Volo/Abp/AspNetCore/TestBase/AbpAspNetCoreIntegratedTestBase.cs b/framework/src/Volo.Abp.AspNetCore.TestBase/Volo/Abp/AspNetCore/TestBase/AbpAspNetCoreIntegratedTestBase.cs
index eb9504570c..c362d5074c 100644
--- a/framework/src/Volo.Abp.AspNetCore.TestBase/Volo/Abp/AspNetCore/TestBase/AbpAspNetCoreIntegratedTestBase.cs
+++ b/framework/src/Volo.Abp.AspNetCore.TestBase/Volo/Abp/AspNetCore/TestBase/AbpAspNetCoreIntegratedTestBase.cs
@@ -7,11 +7,15 @@ using Microsoft.AspNetCore.Routing;
using Microsoft.AspNetCore.TestHost;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
+using Volo.Abp.Modularity;
namespace Volo.Abp.AspNetCore.TestBase;
-public abstract class AbpAspNetCoreIntegratedTestBase : AbpTestBaseWithServiceProvider, IDisposable
- where TStartup : class
+///
+/// Can be a module type or old-style ASP.NET Core Startup class.
+///
+public abstract class AbpAspNetCoreIntegratedTestBase : AbpTestBaseWithServiceProvider, IDisposable
+ where TStartupModule : class
{
protected TestServer Server { get; }
@@ -39,7 +43,15 @@ public abstract class AbpAspNetCoreIntegratedTestBase : AbpTestBaseWit
return Host.CreateDefaultBuilder()
.ConfigureWebHostDefaults(webBuilder =>
{
- webBuilder.UseStartup();
+ if (typeof(TStartupModule).IsAssignableTo())
+ {
+ webBuilder.UseStartup>();
+ }
+ else
+ {
+ webBuilder.UseStartup();
+ }
+
webBuilder.UseAbpTestServer();
})
.UseAutofac()
diff --git a/framework/src/Volo.Abp.AspNetCore.TestBase/Volo/Abp/AspNetCore/TestBase/TestStartup.cs b/framework/src/Volo.Abp.AspNetCore.TestBase/Volo/Abp/AspNetCore/TestBase/TestStartup.cs
new file mode 100644
index 0000000000..be641912c7
--- /dev/null
+++ b/framework/src/Volo.Abp.AspNetCore.TestBase/Volo/Abp/AspNetCore/TestBase/TestStartup.cs
@@ -0,0 +1,18 @@
+using Microsoft.AspNetCore.Builder;
+using Microsoft.Extensions.DependencyInjection;
+using Volo.Abp.Threading;
+
+namespace Volo.Abp.AspNetCore.TestBase;
+
+internal class TestStartup
+{
+ public void ConfigureServices(IServiceCollection services)
+ {
+ AsyncHelper.RunSync(() => services.AddApplicationAsync(typeof(TStartupModule)));
+ }
+
+ public void Configure(IApplicationBuilder app)
+ {
+ AsyncHelper.RunSync(app.InitializeApplicationAsync);
+ }
+}
\ No newline at end of file
diff --git a/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/Builder/AbpAspNetCoreApplicationBuilderExtensions.cs b/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/Builder/AbpAspNetCoreApplicationBuilderExtensions.cs
index 23a73c74c7..684c948975 100644
--- a/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/Builder/AbpAspNetCoreApplicationBuilderExtensions.cs
+++ b/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/Builder/AbpAspNetCoreApplicationBuilderExtensions.cs
@@ -23,7 +23,7 @@ public static class AbpAspNetCoreApplicationBuilderExtensions
.GetRequiredService>()
.Value;
- if (!options.EndpointConfigureActions.Any())
+ if (!options.EndpointConfigureActions.Any() && additionalConfigurationAction == null)
{
return app;
}
@@ -32,15 +32,18 @@ public static class AbpAspNetCoreApplicationBuilderExtensions
{
using (var scope = app.ApplicationServices.CreateScope())
{
- var context = new EndpointRouteBuilderContext(endpoints, scope.ServiceProvider);
-
- foreach (var configureAction in options.EndpointConfigureActions)
+ if (options.EndpointConfigureActions.Any())
{
- configureAction(context);
- }
+ var context = new EndpointRouteBuilderContext(endpoints, scope.ServiceProvider);
- additionalConfigurationAction?.Invoke(endpoints);
+ foreach (var configureAction in options.EndpointConfigureActions)
+ {
+ configureAction(context);
+ }
+ }
}
+
+ additionalConfigurationAction?.Invoke(endpoints);
});
}
}
diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Tracing/AbpCorrelationIdMiddleware.cs b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Tracing/AbpCorrelationIdMiddleware.cs
index 23f1192d1c..33f5de3582 100644
--- a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Tracing/AbpCorrelationIdMiddleware.cs
+++ b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Tracing/AbpCorrelationIdMiddleware.cs
@@ -1,4 +1,5 @@
-using Microsoft.AspNetCore.Http;
+using System;
+using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Options;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
@@ -20,16 +21,31 @@ public class AbpCorrelationIdMiddleware : IMiddleware, ITransientDependency
public async Task InvokeAsync(HttpContext context, RequestDelegate next)
{
- var correlationId = _correlationIdProvider.Get();
+ var correlationId = GetCorrelationIdFromRequest(context);
- try
+ using (_correlationIdProvider.Change(correlationId))
{
- await next(context);
+ try
+ {
+ await next(context);
+ }
+ finally
+ {
+ CheckAndSetCorrelationIdOnResponse(context, _options, correlationId);
+ }
}
- finally
+ }
+
+ protected virtual string GetCorrelationIdFromRequest(HttpContext context)
+ {
+ string correlationId = context.Request.Headers[_options.HttpHeaderName];
+ if (correlationId.IsNullOrEmpty())
{
- CheckAndSetCorrelationIdOnResponse(context, _options, correlationId);
+ correlationId = Guid.NewGuid().ToString("N");
+ context.Request.Headers[_options.HttpHeaderName] = correlationId;
}
+
+ return correlationId;
}
protected virtual void CheckAndSetCorrelationIdOnResponse(
diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Tracing/AspNetCoreCorrelationIdProvider.cs b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Tracing/AspNetCoreCorrelationIdProvider.cs
deleted file mode 100644
index 02e5f91596..0000000000
--- a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Tracing/AspNetCoreCorrelationIdProvider.cs
+++ /dev/null
@@ -1,51 +0,0 @@
-using System;
-using Microsoft.AspNetCore.Http;
-using Microsoft.Extensions.Options;
-using Volo.Abp.DependencyInjection;
-using Volo.Abp.Tracing;
-
-namespace Volo.Abp.AspNetCore.Tracing;
-
-[Dependency(ReplaceServices = true)]
-public class AspNetCoreCorrelationIdProvider : ICorrelationIdProvider, ITransientDependency
-{
- protected IHttpContextAccessor HttpContextAccessor { get; }
- protected AbpCorrelationIdOptions Options { get; }
-
- public AspNetCoreCorrelationIdProvider(
- IHttpContextAccessor httpContextAccessor,
- IOptions options)
- {
- HttpContextAccessor = httpContextAccessor;
- Options = options.Value;
- }
-
- public virtual string Get()
- {
- if (HttpContextAccessor.HttpContext?.Request?.Headers == null)
- {
- return CreateNewCorrelationId();
- }
-
- string correlationId = HttpContextAccessor.HttpContext.Request.Headers[Options.HttpHeaderName];
-
- if (correlationId.IsNullOrEmpty())
- {
- lock (HttpContextAccessor.HttpContext.Request.Headers)
- {
- if (correlationId.IsNullOrEmpty())
- {
- correlationId = CreateNewCorrelationId();
- HttpContextAccessor.HttpContext.Request.Headers[Options.HttpHeaderName] = correlationId;
- }
- }
- }
-
- return correlationId;
- }
-
- protected virtual string CreateNewCorrelationId()
- {
- return Guid.NewGuid().ToString("N");
- }
-}
diff --git a/framework/src/Volo.Abp.Autofac.WebAssembly/Microsoft/AspNetCore/Components/WebAssembly/Hosting/AbpWebAssemblyApplicationCreationOptionsAutofacExtensions.cs b/framework/src/Volo.Abp.Autofac.WebAssembly/Microsoft/AspNetCore/Components/WebAssembly/Hosting/AbpWebAssemblyApplicationCreationOptionsAutofacExtensions.cs
index 62c6f92b9a..dd2ec149c5 100644
--- a/framework/src/Volo.Abp.Autofac.WebAssembly/Microsoft/AspNetCore/Components/WebAssembly/Hosting/AbpWebAssemblyApplicationCreationOptionsAutofacExtensions.cs
+++ b/framework/src/Volo.Abp.Autofac.WebAssembly/Microsoft/AspNetCore/Components/WebAssembly/Hosting/AbpWebAssemblyApplicationCreationOptionsAutofacExtensions.cs
@@ -11,7 +11,7 @@ public static class AbpWebAssemblyApplicationCreationOptionsAutofacExtensions
{
public static void UseAutofac(
[NotNull] this AbpWebAssemblyApplicationCreationOptions options,
- [CanBeNull] Action configure = null)
+ Action? configure = null)
{
options.HostBuilder.Services.AddAutofacServiceProviderFactory();
options.HostBuilder.ConfigureContainer(
diff --git a/framework/src/Volo.Abp.Autofac.WebAssembly/Volo.Abp.Autofac.WebAssembly.csproj b/framework/src/Volo.Abp.Autofac.WebAssembly/Volo.Abp.Autofac.WebAssembly.csproj
index 034c5c1903..1ce2a8154d 100644
--- a/framework/src/Volo.Abp.Autofac.WebAssembly/Volo.Abp.Autofac.WebAssembly.csproj
+++ b/framework/src/Volo.Abp.Autofac.WebAssembly/Volo.Abp.Autofac.WebAssembly.csproj
@@ -5,6 +5,8 @@
net7.0
+ enable
+ Nullable
diff --git a/framework/src/Volo.Abp.Autofac/Autofac/Builder/AbpRegistrationBuilderExtensions.cs b/framework/src/Volo.Abp.Autofac/Autofac/Builder/AbpRegistrationBuilderExtensions.cs
index 03084d8351..4ee9ba5916 100644
--- a/framework/src/Volo.Abp.Autofac/Autofac/Builder/AbpRegistrationBuilderExtensions.cs
+++ b/framework/src/Volo.Abp.Autofac/Autofac/Builder/AbpRegistrationBuilderExtensions.cs
@@ -69,7 +69,7 @@ public static class AbpRegistrationBuilderExtensions
where TActivatorData : ReflectionActivatorData
{
// Enable Property Injection only for types in an assembly containing an AbpModule and without a DisablePropertyInjection attribute on class or properties.
- if (moduleContainer.Modules.Any(m => m.Assembly == implementationType.Assembly) &&
+ if (moduleContainer.Modules.Any(m => m.AllAssemblies.Contains(implementationType.Assembly)) &&
implementationType.GetCustomAttributes(typeof(DisablePropertyInjectionAttribute), true).IsNullOrEmpty())
{
registrationBuilder = registrationBuilder.PropertiesAutowired(new AbpPropertySelector(false));
diff --git a/framework/src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacRegistration.cs b/framework/src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacRegistration.cs
index 241c3dd7a8..56a5d7480c 100644
--- a/framework/src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacRegistration.cs
+++ b/framework/src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacRegistration.cs
@@ -87,7 +87,7 @@ public static class AutofacRegistration
public static void Populate(
this ContainerBuilder builder,
IServiceCollection services,
- object lifetimeScopeTagForSingletons)
+ object? lifetimeScopeTagForSingletons)
{
if (services == null)
{
@@ -134,7 +134,7 @@ public static class AutofacRegistration
private static IRegistrationBuilder ConfigureLifecycle(
this IRegistrationBuilder registrationBuilder,
ServiceLifetime lifecycleKind,
- object lifetimeScopeTagForSingleton)
+ object? lifetimeScopeTagForSingleton)
{
switch (lifecycleKind)
{
@@ -179,7 +179,7 @@ public static class AutofacRegistration
private static void Register(
ContainerBuilder builder,
IServiceCollection services,
- object lifetimeScopeTagForSingletons)
+ object? lifetimeScopeTagForSingletons)
{
var moduleContainer = services.GetSingletonInstance();
var registrationActionList = services.GetRegistrationActionList();
@@ -223,7 +223,7 @@ public static class AutofacRegistration
else
{
builder
- .RegisterInstance(descriptor.ImplementationInstance)
+ .RegisterInstance(descriptor.ImplementationInstance!)
.As(descriptor.ServiceType)
.ConfigureLifecycle(descriptor.Lifetime, null);
}
diff --git a/framework/src/Volo.Abp.Autofac/Microsoft/Extensions/DependencyInjection/AbpAutofacServiceCollectionExtensions.cs b/framework/src/Volo.Abp.Autofac/Microsoft/Extensions/DependencyInjection/AbpAutofacServiceCollectionExtensions.cs
index fe6e57ade8..e249e7e5ac 100644
--- a/framework/src/Volo.Abp.Autofac/Microsoft/Extensions/DependencyInjection/AbpAutofacServiceCollectionExtensions.cs
+++ b/framework/src/Volo.Abp.Autofac/Microsoft/Extensions/DependencyInjection/AbpAutofacServiceCollectionExtensions.cs
@@ -21,7 +21,7 @@ public static class AbpAutofacServiceCollectionExtensions
return builder;
}
- public static IServiceProvider BuildAutofacServiceProvider([NotNull] this IServiceCollection services, Action builderAction = null)
+ public static IServiceProvider BuildAutofacServiceProvider([NotNull] this IServiceCollection services, Action? builderAction = null)
{
return services.BuildServiceProviderFromFactory(builderAction);
}
diff --git a/framework/src/Volo.Abp.Autofac/Volo.Abp.Autofac.csproj b/framework/src/Volo.Abp.Autofac/Volo.Abp.Autofac.csproj
index 32c4eb4e39..cf1c18994a 100644
--- a/framework/src/Volo.Abp.Autofac/Volo.Abp.Autofac.csproj
+++ b/framework/src/Volo.Abp.Autofac/Volo.Abp.Autofac.csproj
@@ -5,6 +5,8 @@
netstandard2.0;netstandard2.1;net7.0
+ enable
+ Nullable
Volo.Abp.Autofac
Volo.Abp.Autofac
$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;
diff --git a/framework/src/Volo.Abp.Autofac/Volo/Abp/Autofac/AbpAutofacServiceProviderFactory.cs b/framework/src/Volo.Abp.Autofac/Volo/Abp/Autofac/AbpAutofacServiceProviderFactory.cs
index 0cc35cbf81..dd8f383c5c 100644
--- a/framework/src/Volo.Abp.Autofac/Volo/Abp/Autofac/AbpAutofacServiceProviderFactory.cs
+++ b/framework/src/Volo.Abp.Autofac/Volo/Abp/Autofac/AbpAutofacServiceProviderFactory.cs
@@ -11,7 +11,7 @@ namespace Volo.Abp.Autofac;
public class AbpAutofacServiceProviderFactory : IServiceProviderFactory
{
private readonly ContainerBuilder _builder;
- private IServiceCollection _services;
+ private IServiceCollection _services = default!;
public AbpAutofacServiceProviderFactory(ContainerBuilder builder)
{
diff --git a/framework/src/Volo.Abp.BlazoriseUI/AbpCrudPageBase.cs b/framework/src/Volo.Abp.BlazoriseUI/AbpCrudPageBase.cs
index 3bcc507e39..f476ecad89 100644
--- a/framework/src/Volo.Abp.BlazoriseUI/AbpCrudPageBase.cs
+++ b/framework/src/Volo.Abp.BlazoriseUI/AbpCrudPageBase.cs
@@ -215,9 +215,9 @@ public abstract class AbpCrudPageBase<
protected async override Task OnInitializedAsync()
{
- await SetPermissionsAsync();
- await SetEntityActionsAsync();
- await SetTableColumnsAsync();
+ await TrySetPermissionsAsync();
+ await TrySetEntityActionsAsync();
+ await TrySetTableColumnsAsync();
await InvokeAsync(StateHasChanged);
}
@@ -231,7 +231,15 @@ public abstract class AbpCrudPageBase<
await base.OnAfterRenderAsync(firstRender);
}
+ private async Task TrySetPermissionsAsync()
+ {
+ if (IsDisposed)
+ {
+ return;
+ }
+ await SetPermissionsAsync();
+ }
protected virtual async Task SetPermissionsAsync()
{
@@ -579,13 +587,34 @@ public abstract class AbpCrudPageBase<
return ValueTask.CompletedTask;
}
+ private async ValueTask TrySetEntityActionsAsync()
+ {
+ if (IsDisposed)
+ {
+ return;
+ }
+
+ await SetEntityActionsAsync();
+ }
+
protected virtual ValueTask SetEntityActionsAsync()
{
return ValueTask.CompletedTask;
}
+
+ private async ValueTask TrySetTableColumnsAsync()
+ {
+ if (IsDisposed)
+ {
+ return;
+ }
+
+ await SetTableColumnsAsync();
+ }
protected virtual ValueTask SetTableColumnsAsync()
{
+
return ValueTask.CompletedTask;
}
diff --git a/framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/CheckExtensionProperty.razor b/framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/CheckExtensionProperty.razor
index eebff3970d..b9ef1e0f8e 100644
--- a/framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/CheckExtensionProperty.razor
+++ b/framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/CheckExtensionProperty.razor
@@ -8,7 +8,7 @@
{
-
+
@PropertyInfo.GetLocalizedDisplayName(StringLocalizerFactory)
diff --git a/framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/DateTimeExtensionProperty.razor b/framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/DateTimeExtensionProperty.razor
index 8fa7f0d777..0500d29c32 100644
--- a/framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/DateTimeExtensionProperty.razor
+++ b/framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/DateTimeExtensionProperty.razor
@@ -13,6 +13,7 @@
diff --git a/framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/ExtensionProperties.razor b/framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/ExtensionProperties.razor
index 9fe96c7a20..aa546793b9 100644
--- a/framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/ExtensionProperties.razor
+++ b/framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/ExtensionProperties.razor
@@ -25,6 +25,7 @@
__builder.AddAttribute(1, "PropertyInfo", propertyInfo);
__builder.AddAttribute(2, "Entity", Entity);
__builder.AddAttribute(3, "LH", LH);
+ __builder.AddAttribute(4, "ModalType", ModalType);
__builder.CloseComponent();
}
}
diff --git a/framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/ExtensionProperties.razor.cs b/framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/ExtensionProperties.razor.cs
index 947069a7ee..d9a1a42d85 100644
--- a/framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/ExtensionProperties.razor.cs
+++ b/framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/ExtensionProperties.razor.cs
@@ -2,6 +2,7 @@
using Microsoft.Extensions.Localization;
using Volo.Abp.AspNetCore.Components.Web;
using Volo.Abp.Data;
+using Volo.Abp.ObjectExtending;
namespace Volo.Abp.BlazoriseUI.Components.ObjectExtending;
@@ -16,4 +17,7 @@ public partial class ExtensionProperties : Component
[Parameter]
public TEntityType Entity { get; set; }
+
+ [Parameter]
+ public ExtensionPropertyModalType? ModalType { get; set; }
}
diff --git a/framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/ExtensionPropertyComponentBase.cs b/framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/ExtensionPropertyComponentBase.cs
index b2a5c1e48d..46f4bd7f51 100644
--- a/framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/ExtensionPropertyComponentBase.cs
+++ b/framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/ExtensionPropertyComponentBase.cs
@@ -33,6 +33,9 @@ public abstract class ExtensionPropertyComponentBase : O
[Parameter]
public AbpBlazorMessageLocalizerHelper LH { get; set; }
+ [Parameter]
+ public ExtensionPropertyModalType? ModalType { get; set; }
+
protected virtual void Validate(ValidatorEventArgs e)
{
e.Status = ValidationStatus.Success;
@@ -65,12 +68,14 @@ public abstract class ExtensionPropertyComponentBase : O
}
e.MemberNames = result.MemberNames;
- e.Status = ValidationStatus.Error;
+ e.Status = ValidationStatus.Error;
e.ErrorText = errorMessage;
break;
}
}
+ protected bool IsReadonlyField => ModalType is ExtensionPropertyModalType.EditModal && PropertyInfo.UI.EditModal.IsReadOnly;
+
private static string GetDefaultErrorMessage(ValidationAttribute validationAttribute)
{
if (validationAttribute is StringLengthAttribute stringLengthAttribute && stringLengthAttribute.MinimumLength != 0)
diff --git a/framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/ExtensionPropertyModalType.cs b/framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/ExtensionPropertyModalType.cs
new file mode 100644
index 0000000000..67cf8d5bb8
--- /dev/null
+++ b/framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/ExtensionPropertyModalType.cs
@@ -0,0 +1,7 @@
+namespace Volo.Abp.BlazoriseUI.Components.ObjectExtending;
+
+public enum ExtensionPropertyModalType : byte
+{
+ CreateModal = 0,
+ EditModal = 1
+}
\ No newline at end of file
diff --git a/framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/LookupExtensionProperty.razor b/framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/LookupExtensionProperty.razor
index 2ea468f1f4..7c32549d51 100644
--- a/framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/LookupExtensionProperty.razor
+++ b/framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/LookupExtensionProperty.razor
@@ -15,6 +15,7 @@
SelectedValueChanged="@SelectedValueChanged"
SearchChanged="@SearchFilterChangedAsync"
Validator="@Validate"
- MinLength="0">
+ MinLength="0"
+ Disabled="IsReadonlyField">
diff --git a/framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/SelectExtensionProperty.razor b/framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/SelectExtensionProperty.razor
index cc1735c26a..605158aec0 100644
--- a/framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/SelectExtensionProperty.razor
+++ b/framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/SelectExtensionProperty.razor
@@ -10,7 +10,7 @@
@foreach (var item in SelectItems)
{
- @item.Text
+ @item.Text
}
diff --git a/framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/TextExtensionProperty.razor b/framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/TextExtensionProperty.razor
index fc8b7b5398..e9d3d7031e 100644
--- a/framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/TextExtensionProperty.razor
+++ b/framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/TextExtensionProperty.razor
@@ -9,7 +9,7 @@
@PropertyInfo.GetLocalizedDisplayName(StringLocalizerFactory)
-
+
diff --git a/framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/TimeExtensionProperty.razor b/framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/TimeExtensionProperty.razor
index 6ad15b2cb5..5d3f1f26af 100644
--- a/framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/TimeExtensionProperty.razor
+++ b/framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/TimeExtensionProperty.razor
@@ -9,7 +9,7 @@
@PropertyInfo.GetLocalizedDisplayName(StringLocalizerFactory) -->
-
+
diff --git a/framework/src/Volo.Abp.Castle.Core/Volo.Abp.Castle.Core.csproj b/framework/src/Volo.Abp.Castle.Core/Volo.Abp.Castle.Core.csproj
index 7125519bb0..d840a3bf69 100644
--- a/framework/src/Volo.Abp.Castle.Core/Volo.Abp.Castle.Core.csproj
+++ b/framework/src/Volo.Abp.Castle.Core/Volo.Abp.Castle.Core.csproj
@@ -5,6 +5,8 @@
netstandard2.0;netstandard2.1;net7.0
+ enable
+ Nullable
Volo.Abp.Castle.Core
Volo.Abp.Castle.Core
$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;
diff --git a/framework/src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/CastleAbpMethodInvocationAdapterBase.cs b/framework/src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/CastleAbpMethodInvocationAdapterBase.cs
index 1a96e20320..138a35c8b0 100644
--- a/framework/src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/CastleAbpMethodInvocationAdapterBase.cs
+++ b/framework/src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/CastleAbpMethodInvocationAdapterBase.cs
@@ -20,7 +20,7 @@ public abstract class CastleAbpMethodInvocationAdapterBase : IAbpMethodInvocatio
public MethodInfo Method => Invocation.MethodInvocationTarget ?? Invocation.Method;
- public object ReturnValue { get; set; }
+ public object ReturnValue { get; set; } = default!;
protected IInvocation Invocation { get; }
@@ -39,7 +39,7 @@ public abstract class CastleAbpMethodInvocationAdapterBase : IAbpMethodInvocatio
var methodParameters = Method.GetParameters();
for (int i = 0; i < methodParameters.Length; i++)
{
- dict[methodParameters[i].Name] = Invocation.Arguments[i];
+ dict[methodParameters[i].Name!] = Invocation.Arguments[i];
}
return dict;
diff --git a/framework/src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/CastleAbpMethodInvocationAdapterWithReturnValue.cs b/framework/src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/CastleAbpMethodInvocationAdapterWithReturnValue.cs
index 6bebcf531e..5e6e2b3e3b 100644
--- a/framework/src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/CastleAbpMethodInvocationAdapterWithReturnValue.cs
+++ b/framework/src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/CastleAbpMethodInvocationAdapterWithReturnValue.cs
@@ -21,6 +21,6 @@ public class CastleAbpMethodInvocationAdapterWithReturnValue : CastleAb
public override async Task ProceedAsync()
{
- ReturnValue = await Proceed(Invocation, ProceedInfo);
+ ReturnValue = (await Proceed(Invocation, ProceedInfo))!;
}
}
diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/LoginCommand.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/LoginCommand.cs
index 0d5b3b31e5..66519a2275 100644
--- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/LoginCommand.cs
+++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/LoginCommand.cs
@@ -17,7 +17,7 @@ namespace Volo.Abp.Cli.Commands;
public class LoginCommand : IConsoleCommand, ITransientDependency
{
public const string Name = "login";
-
+
public ILogger Logger { get; set; }
protected AuthService AuthService { get; }
@@ -122,6 +122,12 @@ public class LoginCommand : IConsoleCommand, ITransientDependency
return;
}
+ if (ex.Message.Contains("RequiresTwoFactor"))
+ {
+ Logger.LogError("Two factor authentication is enabled for your account. Please use `abp login --device` command to login.");
+ return;
+ }
+
if (TryGetErrorMessageFromHtmlPage(ex.Message, out var errorMsg))
{
Logger.LogError(errorMsg);
diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/Services/SuiteAppSettingsService.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/Services/SuiteAppSettingsService.cs
index d274234ded..7d2a61858a 100644
--- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/Services/SuiteAppSettingsService.cs
+++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/Services/SuiteAppSettingsService.cs
@@ -46,6 +46,34 @@ public class SuiteAppSettingsService : ITransientDependency
return Convert.ToInt32(url.Split(":").Last());
}
+
+ public int GetSuitePort()
+ {
+ return GetSuitePort(GetCurrentSuiteVersion());
+ }
+
+ public int GetSuitePort(string version)
+ {
+ var filePath = GetFilePathOrNull(version);
+
+ if (filePath == null)
+ {
+ return DefaultPort;
+ }
+
+ var content = File.ReadAllText(filePath);
+
+ var contentAsJson = JObject.Parse(content);
+
+ var url = contentAsJson["AbpSuite"]?["ApplicationUrl"]?.ToString();
+
+ if (url == null)
+ {
+ return DefaultPort;
+ }
+
+ return Convert.ToInt32(url.Split(":").Last());
+ }
private string GetFilePathOrNull(string version)
{
diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/ConnectionStringRenameStep.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/ConnectionStringRenameStep.cs
new file mode 100644
index 0000000000..ea71eb1c51
--- /dev/null
+++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/ConnectionStringRenameStep.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Linq;
+using Volo.Abp.Cli.ProjectBuilding.Files;
+
+namespace Volo.Abp.Cli.ProjectBuilding.Building;
+
+public class ConnectionStringRenameStep : ProjectBuildPipelineStep
+{
+ public override void Execute(ProjectBuildContext context)
+ {
+ foreach (var fileEntry in context.Files.Where(file => file.Name.EndsWith(CliConsts.AppSettingsJsonFileName, StringComparison.OrdinalIgnoreCase)))
+ {
+ RenameDatabaseName(fileEntry);
+ }
+ }
+
+ private void RenameDatabaseName(FileEntry fileEntry)
+ {
+ fileEntry.SetContent(fileEntry.Content.Replace("MyProjectNamePro", "MyProjectName"));
+ }
+}
\ No newline at end of file
diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/App/AppTemplateBase.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/App/AppTemplateBase.cs
index 8777291c24..5bd0614206 100644
--- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/App/AppTemplateBase.cs
+++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/App/AppTemplateBase.cs
@@ -645,6 +645,11 @@ public abstract class AppTemplateBase : TemplateInfo
{
steps.Add(new ConnectionStringChangeStep());
}
+
+ if (IsPro())
+ {
+ steps.Add(new ConnectionStringRenameStep());
+ }
}
protected void CleanupFolderHierarchy(ProjectBuildContext context, List steps)
diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Microservice/MicroserviceServiceTemplateBase.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Microservice/MicroserviceServiceTemplateBase.cs
index 3e396e8113..13674458ee 100644
--- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Microservice/MicroserviceServiceTemplateBase.cs
+++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Microservice/MicroserviceServiceTemplateBase.cs
@@ -39,7 +39,8 @@ public abstract class MicroserviceServiceTemplateBase : TemplateInfo
SetRandomPortForHostProject(context, steps);
RandomizeStringEncryption(context, steps);
RandomizeAuthServerPassPhrase(context, steps);
-
+ ChangeConnectionString(context, steps);
+
return steps;
}
@@ -75,4 +76,9 @@ public abstract class MicroserviceServiceTemplateBase : TemplateInfo
{
steps.Add(new RandomizeAuthServerPassPhraseStep());
}
+
+ private static void ChangeConnectionString(ProjectBuildContext context, List steps)
+ {
+ steps.Add(new ConnectionStringRenameStep());
+ }
}
diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Module/ModuleTemplateBase.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Module/ModuleTemplateBase.cs
index 5fc263afc3..5229bb167f 100644
--- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Module/ModuleTemplateBase.cs
+++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Module/ModuleTemplateBase.cs
@@ -102,12 +102,17 @@ public abstract class ModuleTemplateBase : TemplateInfo
steps.Add(new UpdateNuGetConfigStep("/NuGet.Config"));
}
- private static void ChangeConnectionString(ProjectBuildContext context, List steps)
+ private void ChangeConnectionString(ProjectBuildContext context, List steps)
{
if (context.BuildArgs.ConnectionString != null)
{
steps.Add(new ConnectionStringChangeStep());
}
+
+ if (IsPro())
+ {
+ steps.Add(new ConnectionStringRenameStep());
+ }
}
private void CleanupFolderHierarchy(ProjectBuildContext context, List steps)
diff --git a/framework/src/Volo.Abp.Core/Volo.Abp.Core.csproj b/framework/src/Volo.Abp.Core/Volo.Abp.Core.csproj
index bf8c9a209d..c250d07eee 100644
--- a/framework/src/Volo.Abp.Core/Volo.Abp.Core.csproj
+++ b/framework/src/Volo.Abp.Core/Volo.Abp.Core.csproj
@@ -28,7 +28,7 @@
-
+
diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationBase.cs b/framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationBase.cs
index 0ccff2db23..ec20467ac9 100644
--- a/framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationBase.cs
+++ b/framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationBase.cs
@@ -188,11 +188,13 @@ public abstract class AbpApplicationBase : IAbpApplication
{
if (!abpModule.SkipAutoServiceRegistration)
{
- var assembly = module.Type.Assembly;
- if (!assemblies.Contains(assembly))
+ foreach (var assembly in module.AllAssemblies)
{
- Services.AddAssembly(assembly);
- assemblies.Add(assembly);
+ if (!assemblies.Contains(assembly))
+ {
+ Services.AddAssembly(assembly);
+ assemblies.Add(assembly);
+ }
}
}
}
@@ -279,11 +281,13 @@ public abstract class AbpApplicationBase : IAbpApplication
{
if (!abpModule.SkipAutoServiceRegistration)
{
- var assembly = module.Type.Assembly;
- if (!assemblies.Contains(assembly))
+ foreach (var assembly in module.AllAssemblies)
{
- Services.AddAssembly(assembly);
- assemblies.Add(assembly);
+ if (!assemblies.Contains(assembly))
+ {
+ Services.AddAssembly(assembly);
+ assemblies.Add(assembly);
+ }
}
}
}
diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/AbpException.cs b/framework/src/Volo.Abp.Core/Volo/Abp/AbpException.cs
index cf779ff7e0..906d3a7fcb 100644
--- a/framework/src/Volo.Abp.Core/Volo/Abp/AbpException.cs
+++ b/framework/src/Volo.Abp.Core/Volo/Abp/AbpException.cs
@@ -13,13 +13,13 @@ public class AbpException : Exception
}
- public AbpException(string message)
+ public AbpException(string? message)
: base(message)
{
}
- public AbpException(string message, Exception innerException)
+ public AbpException(string? message, Exception? innerException)
: base(message, innerException)
{
diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/AbpModuleDescriptor.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/AbpModuleDescriptor.cs
index dcb9cfc817..9bcb7d6a06 100644
--- a/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/AbpModuleDescriptor.cs
+++ b/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/AbpModuleDescriptor.cs
@@ -11,6 +11,8 @@ public class AbpModuleDescriptor : IAbpModuleDescriptor
public Type Type { get; }
public Assembly Assembly { get; }
+
+ public Assembly[] AllAssemblies { get; }
public IAbpModule Instance { get; }
@@ -26,6 +28,7 @@ public class AbpModuleDescriptor : IAbpModuleDescriptor
{
Check.NotNull(type, nameof(type));
Check.NotNull(instance, nameof(instance));
+ AbpModule.CheckAbpModuleType(type);
if (!type.GetTypeInfo().IsAssignableFrom(instance.GetType()))
{
@@ -34,6 +37,7 @@ public class AbpModuleDescriptor : IAbpModuleDescriptor
Type = type;
Assembly = type.Assembly;
+ AllAssemblies = AbpModuleHelper.GetAllAssemblies(type);
Instance = instance;
IsLoadedAsPlugIn = isLoadedAsPlugIn;
diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/AbpModuleDescriptorExtensions.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/AbpModuleDescriptorExtensions.cs
new file mode 100644
index 0000000000..d2e719efb0
--- /dev/null
+++ b/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/AbpModuleDescriptorExtensions.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Linq;
+using System.Reflection;
+
+namespace Volo.Abp.Modularity;
+
+public static class AbpModuleDescriptorExtensions
+{
+ public static Assembly[] GetAdditionalAssemblies(this IAbpModuleDescriptor module)
+ {
+ return module.AllAssemblies.Length <= 1
+ ? Array.Empty()
+ : module.AllAssemblies.Where(x => x != module.Assembly).ToArray();
+ }
+}
\ No newline at end of file
diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/AbpModuleHelper.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/AbpModuleHelper.cs
index 697543409e..eb72664444 100644
--- a/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/AbpModuleHelper.cs
+++ b/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/AbpModuleHelper.cs
@@ -36,6 +36,27 @@ internal static class AbpModuleHelper
return dependencies;
}
+
+ public static Assembly[] GetAllAssemblies(Type moduleType)
+ {
+ var assemblies = new List();
+
+ var additionalAssemblyDescriptors = moduleType
+ .GetCustomAttributes()
+ .OfType();
+
+ foreach (var descriptor in additionalAssemblyDescriptors)
+ {
+ foreach (var assembly in descriptor.GetAssemblies())
+ {
+ assemblies.AddIfNotContains(assembly);
+ }
+ }
+
+ assemblies.Add(moduleType.Assembly);
+
+ return assemblies.ToArray();
+ }
private static void AddModuleAndDependenciesRecursively(
List moduleTypes,
diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/AdditionalAssemblyAttribute.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/AdditionalAssemblyAttribute.cs
new file mode 100644
index 0000000000..ac4165f85e
--- /dev/null
+++ b/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/AdditionalAssemblyAttribute.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Linq;
+using System.Reflection;
+
+namespace Volo.Abp.Modularity;
+
+///
+/// Used to define additional assemblies for a module.
+///
+[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
+public class AdditionalAssemblyAttribute : Attribute, IAdditionalModuleAssemblyProvider
+{
+ public Type[] TypesInAssemblies { get; }
+
+ public AdditionalAssemblyAttribute(params Type[]? typesInAssemblies)
+ {
+ TypesInAssemblies = typesInAssemblies ?? Type.EmptyTypes;
+ }
+
+ public virtual Assembly[] GetAssemblies()
+ {
+ return TypesInAssemblies.Select(t => t.Assembly).Distinct().ToArray();
+ }
+}
\ No newline at end of file
diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/DependsOnAttribute.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/DependsOnAttribute.cs
index 89970859e8..8792d146d9 100644
--- a/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/DependsOnAttribute.cs
+++ b/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/DependsOnAttribute.cs
@@ -1,5 +1,4 @@
using System;
-using JetBrains.Annotations;
namespace Volo.Abp.Modularity;
@@ -9,12 +8,11 @@ namespace Volo.Abp.Modularity;
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
public class DependsOnAttribute : Attribute, IDependedTypesProvider
{
- [NotNull]
public Type[] DependedTypes { get; }
public DependsOnAttribute(params Type[]? dependedTypes)
{
- DependedTypes = dependedTypes ?? new Type[0];
+ DependedTypes = dependedTypes ?? Type.EmptyTypes;
}
public virtual Type[] GetDependedTypes()
diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/IAbpModuleDescriptor.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/IAbpModuleDescriptor.cs
index 8a4fb1e270..8690baa33d 100644
--- a/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/IAbpModuleDescriptor.cs
+++ b/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/IAbpModuleDescriptor.cs
@@ -6,13 +6,36 @@ namespace Volo.Abp.Modularity;
public interface IAbpModuleDescriptor
{
+ ///
+ /// Type of the module class.
+ ///
Type Type { get; }
+ ///
+ /// Main assembly that defines the module .
+ ///
Assembly Assembly { get; }
+
+ ///
+ /// All the assemblies of the module.
+ /// Includes the main and other assemblies defined
+ /// on the module using the attribute.
+ ///
+ Assembly[] AllAssemblies { get; }
+ ///
+ /// The instance of the module class (singleton).
+ ///
IAbpModule Instance { get; }
+ ///
+ /// Is this module loaded as a plug-in?
+ ///
bool IsLoadedAsPlugIn { get; }
+ ///
+ /// Modules on which this module depends on.
+ /// A module can depend on another module using the attribute.
+ ///
IReadOnlyList Dependencies { get; }
-}
+}
\ No newline at end of file
diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/IAdditionalModuleAssemblyProvider.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/IAdditionalModuleAssemblyProvider.cs
new file mode 100644
index 0000000000..3a26d8e918
--- /dev/null
+++ b/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/IAdditionalModuleAssemblyProvider.cs
@@ -0,0 +1,8 @@
+using System.Reflection;
+
+namespace Volo.Abp.Modularity;
+
+public interface IAdditionalModuleAssemblyProvider
+{
+ Assembly[] GetAssemblies();
+}
\ No newline at end of file
diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Reflection/AssemblyFinder.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Reflection/AssemblyFinder.cs
index 4e9a37db1a..602c577050 100644
--- a/framework/src/Volo.Abp.Core/Volo/Abp/Reflection/AssemblyFinder.cs
+++ b/framework/src/Volo.Abp.Core/Volo/Abp/Reflection/AssemblyFinder.cs
@@ -29,7 +29,7 @@ public class AssemblyFinder : IAssemblyFinder
foreach (var module in _moduleContainer.Modules)
{
- assemblies.Add(module.Type.Assembly);
+ assemblies.AddRange(module.AllAssemblies);
}
return assemblies.Distinct().ToImmutableList();
diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Tracing/DefaultCorrelationIdProvider.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Tracing/DefaultCorrelationIdProvider.cs
index e24e81ca21..578587f449 100644
--- a/framework/src/Volo.Abp.Core/Volo/Abp/Tracing/DefaultCorrelationIdProvider.cs
+++ b/framework/src/Volo.Abp.Core/Volo/Abp/Tracing/DefaultCorrelationIdProvider.cs
@@ -1,17 +1,27 @@
using System;
+using System.Threading;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.Tracing;
public class DefaultCorrelationIdProvider : ICorrelationIdProvider, ISingletonDependency
{
- public string Get()
+ private readonly AsyncLocal _currentCorrelationId = new AsyncLocal();
+
+ private string? CorrelationId => _currentCorrelationId.Value;
+
+ public virtual string? Get()
{
- return CreateNewCorrelationId();
+ return CorrelationId;
}
- protected virtual string CreateNewCorrelationId()
+ public virtual IDisposable Change(string? correlationId)
{
- return Guid.NewGuid().ToString("N");
+ var parent = CorrelationId;
+ _currentCorrelationId.Value = correlationId;
+ return new DisposeAction(() =>
+ {
+ _currentCorrelationId.Value = parent;
+ });
}
}
diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Tracing/ICorrelationIdProvider.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Tracing/ICorrelationIdProvider.cs
index dd94ccb93d..06c3200877 100644
--- a/framework/src/Volo.Abp.Core/Volo/Abp/Tracing/ICorrelationIdProvider.cs
+++ b/framework/src/Volo.Abp.Core/Volo/Abp/Tracing/ICorrelationIdProvider.cs
@@ -1,9 +1,10 @@
-using JetBrains.Annotations;
+using System;
namespace Volo.Abp.Tracing;
public interface ICorrelationIdProvider
{
- [NotNull]
- string Get();
+ string? Get();
+
+ IDisposable Change(string? correlationId);
}
diff --git a/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/IDaprSerializer.cs b/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/IDaprSerializer.cs
index 9a8b4c9520..1d1861cd97 100644
--- a/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/IDaprSerializer.cs
+++ b/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/IDaprSerializer.cs
@@ -6,6 +6,8 @@ public interface IDaprSerializer
{
byte[] Serialize(object obj);
+ string SerializeToString(object obj);
+
object Deserialize(byte[] value, Type type);
object Deserialize(string value, Type type);
diff --git a/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/Utf8JsonDaprSerializer.cs b/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/Utf8JsonDaprSerializer.cs
index c0924f775b..a1a8324598 100644
--- a/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/Utf8JsonDaprSerializer.cs
+++ b/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/Utf8JsonDaprSerializer.cs
@@ -19,6 +19,11 @@ public class Utf8JsonDaprSerializer : IDaprSerializer, ITransientDependency
return Encoding.UTF8.GetBytes(_jsonSerializer.Serialize(obj));
}
+ public string SerializeToString(object obj)
+ {
+ return _jsonSerializer.Serialize(obj);
+ }
+
public object Deserialize(byte[] value, Type type)
{
return _jsonSerializer.Deserialize(type, Encoding.UTF8.GetString(value));
diff --git a/framework/src/Volo.Abp.Data/Volo.Abp.Data.csproj b/framework/src/Volo.Abp.Data/Volo.Abp.Data.csproj
index b5d2589b19..751042e62c 100644
--- a/framework/src/Volo.Abp.Data/Volo.Abp.Data.csproj
+++ b/framework/src/Volo.Abp.Data/Volo.Abp.Data.csproj
@@ -5,6 +5,8 @@
netstandard2.0;netstandard2.1;net7.0
+ enable
+ Nullable
Volo.Abp.Data
Volo.Abp.Data
$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;
diff --git a/framework/src/Volo.Abp.Data/Volo/Abp/Data/AbpCommonDbProperties.cs b/framework/src/Volo.Abp.Data/Volo/Abp/Data/AbpCommonDbProperties.cs
index eacedc2408..16236a4e10 100644
--- a/framework/src/Volo.Abp.Data/Volo/Abp/Data/AbpCommonDbProperties.cs
+++ b/framework/src/Volo.Abp.Data/Volo/Abp/Data/AbpCommonDbProperties.cs
@@ -13,5 +13,5 @@ public static class AbpCommonDbProperties
///
/// Default value: null.
///
- public static string DbSchema { get; set; } = null;
+ public static string? DbSchema { get; set; } = null;
}
diff --git a/framework/src/Volo.Abp.Data/Volo/Abp/Data/AbpDataMigrationEnvironmentExtensions.cs b/framework/src/Volo.Abp.Data/Volo/Abp/Data/AbpDataMigrationEnvironmentExtensions.cs
index 796b547164..18b990ce73 100644
--- a/framework/src/Volo.Abp.Data/Volo/Abp/Data/AbpDataMigrationEnvironmentExtensions.cs
+++ b/framework/src/Volo.Abp.Data/Volo/Abp/Data/AbpDataMigrationEnvironmentExtensions.cs
@@ -6,17 +6,17 @@ namespace Volo.Abp.Data;
public static class AbpDataMigrationEnvironmentExtensions
{
- public static void AddDataMigrationEnvironment(this AbpApplicationCreationOptions options, AbpDataMigrationEnvironment environment = null)
+ public static void AddDataMigrationEnvironment(this AbpApplicationCreationOptions options, AbpDataMigrationEnvironment? environment = null)
{
options.Services.AddDataMigrationEnvironment(environment ?? new AbpDataMigrationEnvironment());
}
- public static void AddDataMigrationEnvironment(this IServiceCollection services, AbpDataMigrationEnvironment environment = null)
+ public static void AddDataMigrationEnvironment(this IServiceCollection services, AbpDataMigrationEnvironment? environment = null)
{
services.AddObjectAccessor(environment ?? new AbpDataMigrationEnvironment());
}
- public static AbpDataMigrationEnvironment GetDataMigrationEnvironment(this IServiceCollection services)
+ public static AbpDataMigrationEnvironment? GetDataMigrationEnvironment(this IServiceCollection services)
{
return services.GetObjectOrNull();
}
@@ -26,7 +26,7 @@ public static class AbpDataMigrationEnvironmentExtensions
return services.GetDataMigrationEnvironment() != null;
}
- public static AbpDataMigrationEnvironment GetDataMigrationEnvironment(this IServiceProvider serviceProvider)
+ public static AbpDataMigrationEnvironment? GetDataMigrationEnvironment(this IServiceProvider serviceProvider)
{
return serviceProvider.GetService>()?.Value;
}
diff --git a/framework/src/Volo.Abp.Data/Volo/Abp/Data/AbpDatabaseInfo.cs b/framework/src/Volo.Abp.Data/Volo/Abp/Data/AbpDatabaseInfo.cs
index c4f8d9674b..069b7bb85b 100644
--- a/framework/src/Volo.Abp.Data/Volo/Abp/Data/AbpDatabaseInfo.cs
+++ b/framework/src/Volo.Abp.Data/Volo/Abp/Data/AbpDatabaseInfo.cs
@@ -24,4 +24,16 @@ public class AbpDatabaseInfo
DatabaseName = databaseName;
MappedConnections = new HashSet();
}
+
+ ///
+ /// Shortcut method to add one or multiple connections to the collection.
+ ///
+ ///
+ public void MapConnection(params string[] connectionNames)
+ {
+ foreach (var connectionName in connectionNames)
+ {
+ MappedConnections.AddIfNotContains(connectionName);
+ }
+ }
}
diff --git a/framework/src/Volo.Abp.Data/Volo/Abp/Data/AbpDatabaseInfoDictionary.cs b/framework/src/Volo.Abp.Data/Volo/Abp/Data/AbpDatabaseInfoDictionary.cs
index 2f17b320dd..06334be6db 100644
--- a/framework/src/Volo.Abp.Data/Volo/Abp/Data/AbpDatabaseInfoDictionary.cs
+++ b/framework/src/Volo.Abp.Data/Volo/Abp/Data/AbpDatabaseInfoDictionary.cs
@@ -13,8 +13,7 @@ public class AbpDatabaseInfoDictionary : Dictionary
ConnectionIndex = new Dictionary();
}
- [CanBeNull]
- public AbpDatabaseInfo GetMappedDatabaseOrNull(string connectionStringName)
+ public AbpDatabaseInfo? GetMappedDatabaseOrNull(string connectionStringName)
{
return ConnectionIndex.GetOrDefault(connectionStringName);
}
diff --git a/framework/src/Volo.Abp.Data/Volo/Abp/Data/AbpDbConnectionOptions.cs b/framework/src/Volo.Abp.Data/Volo/Abp/Data/AbpDbConnectionOptions.cs
index a8101e2f7c..3e27ae97ae 100644
--- a/framework/src/Volo.Abp.Data/Volo/Abp/Data/AbpDbConnectionOptions.cs
+++ b/framework/src/Volo.Abp.Data/Volo/Abp/Data/AbpDbConnectionOptions.cs
@@ -15,7 +15,7 @@ public class AbpDbConnectionOptions
Databases = new AbpDatabaseInfoDictionary();
}
- public string GetConnectionStringOrNull(
+ public string? GetConnectionStringOrNull(
string connectionStringName,
bool fallbackToDatabaseMappings = true,
bool fallbackToDefault = true)
diff --git a/framework/src/Volo.Abp.Data/Volo/Abp/Data/AppliedDatabaseMigrationsEto.cs b/framework/src/Volo.Abp.Data/Volo/Abp/Data/AppliedDatabaseMigrationsEto.cs
new file mode 100644
index 0000000000..53fae25737
--- /dev/null
+++ b/framework/src/Volo.Abp.Data/Volo/Abp/Data/AppliedDatabaseMigrationsEto.cs
@@ -0,0 +1,12 @@
+using System;
+using Volo.Abp.EventBus;
+
+namespace Volo.Abp.Data;
+
+[Serializable]
+[EventName("abp.data.applied_database_migrations")]
+public class AppliedDatabaseMigrationsEto
+{
+ public string DatabaseName { get; set; } = default!;
+ public Guid? TenantId { get; set; }
+}
\ No newline at end of file
diff --git a/framework/src/Volo.Abp.Data/Volo/Abp/Data/ApplyDatabaseMigrationsEto.cs b/framework/src/Volo.Abp.Data/Volo/Abp/Data/ApplyDatabaseMigrationsEto.cs
index 061ce94a79..8ac1290fad 100644
--- a/framework/src/Volo.Abp.Data/Volo/Abp/Data/ApplyDatabaseMigrationsEto.cs
+++ b/framework/src/Volo.Abp.Data/Volo/Abp/Data/ApplyDatabaseMigrationsEto.cs
@@ -10,5 +10,5 @@ public class ApplyDatabaseMigrationsEto : EtoBase
{
public Guid? TenantId { get; set; }
- public string DatabaseName { get; set; }
+ public string DatabaseName { get; set; } = default!;
}
diff --git a/framework/src/Volo.Abp.Data/Volo/Abp/Data/ConcurrencyStampExtensions.cs b/framework/src/Volo.Abp.Data/Volo/Abp/Data/ConcurrencyStampExtensions.cs
index 4b0cd87252..84232a7a88 100644
--- a/framework/src/Volo.Abp.Data/Volo/Abp/Data/ConcurrencyStampExtensions.cs
+++ b/framework/src/Volo.Abp.Data/Volo/Abp/Data/ConcurrencyStampExtensions.cs
@@ -7,11 +7,11 @@ namespace Volo.Abp.Data;
public static class ConcurrencyStampExtensions
{
- public static void SetConcurrencyStampIfNotNull(this IHasConcurrencyStamp entity, [CanBeNull] string concurrencyStamp)
+ public static void SetConcurrencyStampIfNotNull(this IHasConcurrencyStamp entity, string? concurrencyStamp)
{
if (!concurrencyStamp.IsNullOrEmpty())
{
- entity.ConcurrencyStamp = concurrencyStamp;
+ entity.ConcurrencyStamp = concurrencyStamp!;
}
}
}
diff --git a/framework/src/Volo.Abp.Data/Volo/Abp/Data/ConnectionStringNameAttribute.cs b/framework/src/Volo.Abp.Data/Volo/Abp/Data/ConnectionStringNameAttribute.cs
index 9e028eef12..e5936ab932 100644
--- a/framework/src/Volo.Abp.Data/Volo/Abp/Data/ConnectionStringNameAttribute.cs
+++ b/framework/src/Volo.Abp.Data/Volo/Abp/Data/ConnectionStringNameAttribute.cs
@@ -27,7 +27,7 @@ public class ConnectionStringNameAttribute : Attribute
if (nameAttribute == null)
{
- return type.FullName;
+ return type.FullName!;
}
return nameAttribute.Name;
diff --git a/framework/src/Volo.Abp.Data/Volo/Abp/Data/ConnectionStrings.cs b/framework/src/Volo.Abp.Data/Volo/Abp/Data/ConnectionStrings.cs
index ca84675c10..22354defc4 100644
--- a/framework/src/Volo.Abp.Data/Volo/Abp/Data/ConnectionStrings.cs
+++ b/framework/src/Volo.Abp.Data/Volo/Abp/Data/ConnectionStrings.cs
@@ -4,11 +4,11 @@ using System.Collections.Generic;
namespace Volo.Abp.Data;
[Serializable]
-public class ConnectionStrings : Dictionary
+public class ConnectionStrings : Dictionary
{
public const string DefaultConnectionStringName = "Default";
- public string Default {
+ public string? Default {
get => this.GetOrDefault(DefaultConnectionStringName);
set => this[DefaultConnectionStringName] = value;
}
diff --git a/framework/src/Volo.Abp.Data/Volo/Abp/Data/DataFilter.cs b/framework/src/Volo.Abp.Data/Volo/Abp/Data/DataFilter.cs
index cca494bb07..40ff5cdf70 100644
--- a/framework/src/Volo.Abp.Data/Volo/Abp/Data/DataFilter.cs
+++ b/framework/src/Volo.Abp.Data/Volo/Abp/Data/DataFilter.cs
@@ -42,10 +42,10 @@ public class DataFilter : IDataFilter, ISingletonDependency
private IDataFilter GetFilter()
where TFilter : class
{
- return _filters.GetOrAdd(
+ return (_filters.GetOrAdd(
typeof(TFilter),
- factory: () => _serviceProvider.GetRequiredService>()
- ) as IDataFilter;
+ factory: () => _serviceProvider.GetRequiredService>()
+ ) as IDataFilter)!;
}
}
@@ -55,7 +55,7 @@ public class DataFilter : IDataFilter
public bool IsEnabled {
get {
EnsureInitialized();
- return _filter.Value.IsEnabled;
+ return _filter.Value!.IsEnabled;
}
}
@@ -76,7 +76,7 @@ public class DataFilter : IDataFilter
return NullDisposable.Instance;
}
- _filter.Value.IsEnabled = true;
+ _filter.Value!.IsEnabled = true;
return new DisposeAction(() => Disable());
}
@@ -88,7 +88,7 @@ public class DataFilter : IDataFilter
return NullDisposable.Instance;
}
- _filter.Value.IsEnabled = false;
+ _filter.Value!.IsEnabled = false;
return new DisposeAction(() => Enable());
}
diff --git a/framework/src/Volo.Abp.Data/Volo/Abp/Data/DataSeedContext.cs b/framework/src/Volo.Abp.Data/Volo/Abp/Data/DataSeedContext.cs
index 783fddecb3..3a4aa1c0d7 100644
--- a/framework/src/Volo.Abp.Data/Volo/Abp/Data/DataSeedContext.cs
+++ b/framework/src/Volo.Abp.Data/Volo/Abp/Data/DataSeedContext.cs
@@ -16,8 +16,7 @@ public class DataSeedContext
/// Returns the value in the dictionary by given .
/// Returns null if given is not present in the dictionary.
///
- [CanBeNull]
- public object this[string name] {
+ public object? this[string name] {
get => Properties.GetOrDefault(name);
set => Properties[name] = value;
}
@@ -26,19 +25,19 @@ public class DataSeedContext
/// Can be used to get/set custom properties.
///
[NotNull]
- public Dictionary Properties { get; }
+ public Dictionary Properties { get; }
public DataSeedContext(Guid? tenantId = null)
{
TenantId = tenantId;
- Properties = new Dictionary();
+ Properties = new Dictionary();
}
///
/// Sets a property in the dictionary.
/// This is a shortcut for nested calls on this object.
///
- public virtual DataSeedContext WithProperty(string key, object value)
+ public virtual DataSeedContext WithProperty(string key, object? value)
{
Properties[key] = value;
return this;
diff --git a/framework/src/Volo.Abp.Data/Volo/Abp/Data/DataSeeder.cs b/framework/src/Volo.Abp.Data/Volo/Abp/Data/DataSeeder.cs
index 45729fcb86..83586e8e70 100644
--- a/framework/src/Volo.Abp.Data/Volo/Abp/Data/DataSeeder.cs
+++ b/framework/src/Volo.Abp.Data/Volo/Abp/Data/DataSeeder.cs
@@ -33,9 +33,9 @@ public class DataSeeder : IDataSeeder, ITransientDependency
foreach (var contributorType in Options.Contributors)
{
var options = context.Properties.TryGetValue(DataSeederExtensions.SeedInSeparateUowOptions, out var uowOptions)
- ? (AbpUnitOfWorkOptions) uowOptions
+ ? (AbpUnitOfWorkOptions) uowOptions!
: new AbpUnitOfWorkOptions();
- var requiresNew = context.Properties.TryGetValue(DataSeederExtensions.SeedInSeparateUowRequiresNew, out var obj) && (bool) obj;
+ var requiresNew = context.Properties.TryGetValue(DataSeederExtensions.SeedInSeparateUowRequiresNew, out var obj) && (bool) obj!;
using (var uow = manager.Begin(options, requiresNew))
{
diff --git a/framework/src/Volo.Abp.Data/Volo/Abp/Data/DataSeederExtensions.cs b/framework/src/Volo.Abp.Data/Volo/Abp/Data/DataSeederExtensions.cs
index bd17736b46..f8f3cf8dc5 100644
--- a/framework/src/Volo.Abp.Data/Volo/Abp/Data/DataSeederExtensions.cs
+++ b/framework/src/Volo.Abp.Data/Volo/Abp/Data/DataSeederExtensions.cs
@@ -15,7 +15,7 @@ public static class DataSeederExtensions
return seeder.SeedAsync(new DataSeedContext(tenantId));
}
- public static Task SeedInSeparateUowAsync(this IDataSeeder seeder, Guid? tenantId = null, AbpUnitOfWorkOptions options = null, bool requiresNew = false)
+ public static Task SeedInSeparateUowAsync(this IDataSeeder seeder, Guid? tenantId = null, AbpUnitOfWorkOptions? options = null, bool requiresNew = false)
{
var context = new DataSeedContext(tenantId);
context.WithProperty(SeedInSeparateUow, true);
diff --git a/framework/src/Volo.Abp.Data/Volo/Abp/Data/DefaultConnectionStringResolver.cs b/framework/src/Volo.Abp.Data/Volo/Abp/Data/DefaultConnectionStringResolver.cs
index d3edbd30b0..257c0be663 100644
--- a/framework/src/Volo.Abp.Data/Volo/Abp/Data/DefaultConnectionStringResolver.cs
+++ b/framework/src/Volo.Abp.Data/Volo/Abp/Data/DefaultConnectionStringResolver.cs
@@ -16,17 +16,17 @@ public class DefaultConnectionStringResolver : IConnectionStringResolver, ITrans
}
[Obsolete("Use ResolveAsync method.")]
- public virtual string Resolve(string connectionStringName = null)
+ public virtual string Resolve(string? connectionStringName = null)
{
- return ResolveInternal(connectionStringName);
+ return ResolveInternal(connectionStringName)!;
}
- public virtual Task ResolveAsync(string connectionStringName = null)
+ public virtual Task ResolveAsync(string? connectionStringName = null)
{
- return Task.FromResult(ResolveInternal(connectionStringName));
+ return Task.FromResult(ResolveInternal(connectionStringName))!;
}
- private string ResolveInternal(string connectionStringName)
+ private string? ResolveInternal(string? connectionStringName)
{
if (connectionStringName == null)
{
diff --git a/framework/src/Volo.Abp.Data/Volo/Abp/Data/IConnectionStringResolver.cs b/framework/src/Volo.Abp.Data/Volo/Abp/Data/IConnectionStringResolver.cs
index 793fb309cb..8ef7df4e60 100644
--- a/framework/src/Volo.Abp.Data/Volo/Abp/Data/IConnectionStringResolver.cs
+++ b/framework/src/Volo.Abp.Data/Volo/Abp/Data/IConnectionStringResolver.cs
@@ -8,8 +8,8 @@ public interface IConnectionStringResolver
{
[NotNull]
[Obsolete("Use ResolveAsync method.")]
- string Resolve(string connectionStringName = null);
+ string Resolve(string? connectionStringName = null);
[NotNull]
- Task ResolveAsync(string connectionStringName = null);
+ Task ResolveAsync(string? connectionStringName = null);
}
diff --git a/framework/src/Volo.Abp.EntityFrameworkCore.Sqlite/Volo/Abp/EntityFrameworkCore/AbpDbContextConfigurationContextSqliteExtensions.cs b/framework/src/Volo.Abp.EntityFrameworkCore.Sqlite/Volo/Abp/EntityFrameworkCore/AbpDbContextConfigurationContextSqliteExtensions.cs
index 395cc4de7e..6dea2a336b 100644
--- a/framework/src/Volo.Abp.EntityFrameworkCore.Sqlite/Volo/Abp/EntityFrameworkCore/AbpDbContextConfigurationContextSqliteExtensions.cs
+++ b/framework/src/Volo.Abp.EntityFrameworkCore.Sqlite/Volo/Abp/EntityFrameworkCore/AbpDbContextConfigurationContextSqliteExtensions.cs
@@ -1,4 +1,5 @@
using System;
+using System.Data.Common;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
@@ -29,4 +30,27 @@ public static class AbpDbContextConfigurationContextSqliteExtensions
});
}
}
+
+ public static DbContextOptionsBuilder UseSqlite(
+ [NotNull] this AbpDbContextConfigurationContext context,
+ DbConnection connection,
+ [CanBeNull] Action sqliteOptionsAction = null)
+ {
+ if (context.ExistingConnection != null)
+ {
+ return context.DbContextOptions.UseSqlite(context.ExistingConnection, optionsBuilder =>
+ {
+ optionsBuilder.UseQuerySplittingBehavior(QuerySplittingBehavior.SplitQuery);
+ sqliteOptionsAction?.Invoke(optionsBuilder);
+ });
+ }
+ else
+ {
+ return context.DbContextOptions.UseSqlite(connection, optionsBuilder =>
+ {
+ optionsBuilder.UseQuerySplittingBehavior(QuerySplittingBehavior.SplitQuery);
+ sqliteOptionsAction?.Invoke(optionsBuilder);
+ });
+ }
+ }
}
diff --git a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DistributedEvents/IncomingEventRecord.cs b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DistributedEvents/IncomingEventRecord.cs
index c891f3a406..986c19bbbf 100644
--- a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DistributedEvents/IncomingEventRecord.cs
+++ b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DistributedEvents/IncomingEventRecord.cs
@@ -48,13 +48,20 @@ public class IncomingEventRecord :
public IncomingEventInfo ToIncomingEventInfo()
{
- return new IncomingEventInfo(
+ var info = new IncomingEventInfo(
Id,
MessageId,
EventName,
EventData,
CreationTime
);
+
+ foreach (var property in ExtraProperties)
+ {
+ info.SetProperty(property.Key, property.Value);
+ }
+
+ return info;
}
public void MarkAsProcessed(DateTime processedTime)
diff --git a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DistributedEvents/OutgoingEventRecord.cs b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DistributedEvents/OutgoingEventRecord.cs
index 41c4d41ce4..fe639411a2 100644
--- a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DistributedEvents/OutgoingEventRecord.cs
+++ b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DistributedEvents/OutgoingEventRecord.cs
@@ -41,11 +41,18 @@ public class OutgoingEventRecord :
public OutgoingEventInfo ToOutgoingEventInfo()
{
- return new OutgoingEventInfo(
+ var info = new OutgoingEventInfo(
Id,
EventName,
EventData,
CreationTime
);
+
+ foreach (var property in ExtraProperties)
+ {
+ info.SetProperty(property.Key, property.Value);
+ }
+
+ return info;
}
}
diff --git a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/Migrations/EfCoreDatabaseMigrationEventHandlerBase.cs b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/Migrations/EfCoreDatabaseMigrationEventHandlerBase.cs
new file mode 100644
index 0000000000..d9fc7db914
--- /dev/null
+++ b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/Migrations/EfCoreDatabaseMigrationEventHandlerBase.cs
@@ -0,0 +1,318 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
+using Volo.Abp.Data;
+using Volo.Abp.DependencyInjection;
+using Volo.Abp.Domain.Entities.Events.Distributed;
+using Volo.Abp.EventBus.Distributed;
+using Volo.Abp.MultiTenancy;
+using Volo.Abp.Uow;
+
+namespace Volo.Abp.EntityFrameworkCore.Migrations;
+
+public abstract class EfCoreDatabaseMigrationEventHandlerBase :
+ IDistributedEventHandler,
+ IDistributedEventHandler,
+ IDistributedEventHandler,
+ ITransientDependency
+ where TDbContext : DbContext, IEfCoreDbContext
+{
+ protected string DatabaseName { get; }
+
+ protected const string TryCountPropertyName = "__TryCount";
+
+ protected int MaxEventTryCount { get; set; } = 3;
+
+ ///
+ /// As milliseconds.
+ ///
+ protected int MinValueToWaitOnFailure { get; set; } = 5000;
+
+ ///
+ /// As milliseconds.
+ ///
+ protected int MaxValueToWaitOnFailure { get; set; } = 15000;
+
+ protected ICurrentTenant CurrentTenant { get; }
+ protected IUnitOfWorkManager UnitOfWorkManager { get; }
+ protected ITenantStore TenantStore { get; }
+ protected IDistributedEventBus DistributedEventBus { get; }
+ protected ILogger> Logger { get; }
+
+ protected EfCoreDatabaseMigrationEventHandlerBase(
+ string databaseName,
+ ICurrentTenant currentTenant,
+ IUnitOfWorkManager unitOfWorkManager,
+ ITenantStore tenantStore,
+ IDistributedEventBus distributedEventBus,
+ ILoggerFactory loggerFactory)
+ {
+ CurrentTenant = currentTenant;
+ UnitOfWorkManager = unitOfWorkManager;
+ TenantStore = tenantStore;
+ DatabaseName = databaseName;
+ DistributedEventBus = distributedEventBus;
+
+ Logger = loggerFactory.CreateLogger>();
+ }
+
+ public virtual async Task HandleEventAsync(ApplyDatabaseMigrationsEto eventData)
+ {
+ if (eventData.DatabaseName != DatabaseName)
+ {
+ return;
+ }
+
+ var schemaMigrated = false;
+ try
+ {
+ schemaMigrated = await MigrateDatabaseSchemaAsync(eventData.TenantId);
+ await SeedAsync(eventData.TenantId);
+
+ if (schemaMigrated)
+ {
+ await DistributedEventBus.PublishAsync(
+ new AppliedDatabaseMigrationsEto
+ {
+ DatabaseName = DatabaseName,
+ TenantId = eventData.TenantId
+ }
+ );
+ }
+ }
+ catch (Exception ex)
+ {
+ await HandleErrorOnApplyDatabaseMigrationAsync(eventData, ex);
+ }
+
+ await AfterApplyDatabaseMigrations(eventData, schemaMigrated);
+ }
+
+ protected virtual Task AfterApplyDatabaseMigrations(ApplyDatabaseMigrationsEto eventData, bool schemaMigrated)
+ {
+ return Task.CompletedTask;
+ }
+
+ public virtual async Task HandleEventAsync(TenantCreatedEto eventData)
+ {
+ var schemaMigrated = false;
+ try
+ {
+ schemaMigrated = await MigrateDatabaseSchemaAsync(eventData.Id);
+ await SeedAsync(eventData.Id);
+
+ if (schemaMigrated)
+ {
+ await DistributedEventBus.PublishAsync(
+ new AppliedDatabaseMigrationsEto
+ {
+ DatabaseName = DatabaseName,
+ TenantId = eventData.Id
+ }
+ );
+ }
+ }
+ catch (Exception ex)
+ {
+ await HandleErrorTenantCreatedAsync(eventData, ex);
+ }
+
+ await AfterTenantCreated(eventData, schemaMigrated);
+ }
+
+ protected virtual Task AfterTenantCreated(TenantCreatedEto eventData, bool schemaMigrated)
+ {
+ return Task.CompletedTask;
+ }
+
+ public virtual async Task HandleEventAsync(TenantConnectionStringUpdatedEto eventData)
+ {
+ if (eventData.ConnectionStringName != DatabaseName &&
+ eventData.ConnectionStringName != Volo.Abp.Data.ConnectionStrings.DefaultConnectionStringName ||
+ eventData.NewValue.IsNullOrWhiteSpace())
+ {
+ return;
+ }
+
+ var schemaMigrated = false;
+ try
+ {
+ schemaMigrated = await MigrateDatabaseSchemaAsync(eventData.Id);
+ await SeedAsync(eventData.Id);
+
+ if (schemaMigrated)
+ {
+ await DistributedEventBus.PublishAsync(
+ new AppliedDatabaseMigrationsEto
+ {
+ DatabaseName = DatabaseName,
+ TenantId = eventData.Id
+ }
+ );
+ }
+ }
+ catch (Exception ex)
+ {
+ await HandleErrorTenantConnectionStringUpdatedAsync(eventData, ex);
+ }
+
+ await AfterTenantConnectionStringUpdated(eventData, schemaMigrated);
+ }
+
+ protected virtual Task AfterTenantConnectionStringUpdated(TenantConnectionStringUpdatedEto eventData,
+ bool schemaMigrated)
+ {
+ return Task.CompletedTask;
+ }
+
+ protected virtual Task SeedAsync(Guid? tenantId)
+ {
+ return Task.CompletedTask;
+ }
+
+ ///
+ /// Apply pending EF Core schema migrations to the database.
+ /// Returns true if any migration has applied.
+ ///
+ protected virtual async Task MigrateDatabaseSchemaAsync(Guid? tenantId)
+ {
+ var result = false;
+
+ using (CurrentTenant.Change(tenantId))
+ {
+ using (var uow = UnitOfWorkManager.Begin(requiresNew: true, isTransactional: false))
+ {
+ async Task MigrateDatabaseSchemaWithDbContextAsync()
+ {
+ var dbContext = await uow.ServiceProvider
+ .GetRequiredService>()
+ .GetDbContextAsync();
+
+ if ((await dbContext.Database.GetPendingMigrationsAsync()).Any())
+ {
+ await dbContext.Database.MigrateAsync();
+ return true;
+ }
+
+ return false;
+ }
+
+ if (tenantId == null)
+ {
+ //Migrating the host database
+ Logger.LogInformation($"Migrating database of host. Database Name = {DatabaseName}");
+ result = await MigrateDatabaseSchemaWithDbContextAsync();
+ }
+ else
+ {
+ var tenantConfiguration = await TenantStore.FindAsync(tenantId.Value);
+ if (!tenantConfiguration.ConnectionStrings.Default.IsNullOrWhiteSpace() ||
+ !tenantConfiguration.ConnectionStrings.GetOrDefault(DatabaseName).IsNullOrWhiteSpace())
+ {
+ //Migrating the tenant database (only if tenant has a separate database)
+ Logger.LogInformation(
+ $"Migrating separate database of tenant. Database Name = {DatabaseName}, TenantId = {tenantId}");
+ result = await MigrateDatabaseSchemaWithDbContextAsync();
+ }
+ }
+
+ await uow.CompleteAsync();
+ }
+ }
+
+ return result;
+ }
+
+ protected virtual async Task HandleErrorOnApplyDatabaseMigrationAsync(
+ ApplyDatabaseMigrationsEto eventData,
+ Exception exception)
+ {
+ var tryCount = IncrementEventTryCount(eventData);
+ if (tryCount <= MaxEventTryCount)
+ {
+ Logger.LogWarning(
+ $"Could not apply database migrations. Re-queueing the operation. TenantId = {eventData.TenantId}, Database Name = {eventData.DatabaseName}.");
+ Logger.LogException(exception, LogLevel.Warning);
+
+ await Task.Delay(RandomHelper.GetRandom(MinValueToWaitOnFailure, MaxValueToWaitOnFailure));
+ await DistributedEventBus.PublishAsync(eventData);
+ }
+ else
+ {
+ Logger.LogError(
+ $"Could not apply database migrations. Canceling the operation. TenantId = {eventData.TenantId}, DatabaseName = {eventData.DatabaseName}.");
+ Logger.LogException(exception);
+ }
+ }
+
+ protected virtual async Task HandleErrorTenantCreatedAsync(
+ TenantCreatedEto eventData,
+ Exception exception)
+ {
+ var tryCount = IncrementEventTryCount(eventData);
+ if (tryCount <= MaxEventTryCount)
+ {
+ Logger.LogWarning(
+ $"Could not perform tenant created event. Re-queueing the operation. TenantId = {eventData.Id}, TenantName = {eventData.Name}.");
+ Logger.LogException(exception, LogLevel.Warning);
+
+ await Task.Delay(RandomHelper.GetRandom(5000, 15000));
+ await DistributedEventBus.PublishAsync(eventData);
+ }
+ else
+ {
+ Logger.LogError(
+ $"Could not perform tenant created event. Canceling the operation. TenantId = {eventData.Id}, TenantName = {eventData.Name}.");
+ Logger.LogException(exception);
+ }
+ }
+
+ protected virtual async Task HandleErrorTenantConnectionStringUpdatedAsync(
+ TenantConnectionStringUpdatedEto eventData,
+ Exception exception)
+ {
+ var tryCount = IncrementEventTryCount(eventData);
+ if (tryCount <= MaxEventTryCount)
+ {
+ Logger.LogWarning(
+ $"Could not perform tenant connection string updated event. Re-queueing the operation. TenantId = {eventData.Id}, TenantName = {eventData.Name}.");
+ Logger.LogException(exception, LogLevel.Warning);
+
+ await Task.Delay(RandomHelper.GetRandom(5000, 15000));
+ await DistributedEventBus.PublishAsync(eventData);
+ }
+ else
+ {
+ Logger.LogError(
+ $"Could not perform tenant connection string updated event. Canceling the operation. TenantId = {eventData.Id}, TenantName = {eventData.Name}.");
+ Logger.LogException(exception);
+ }
+ }
+
+ private static int GetEventTryCount(EtoBase eventData)
+ {
+ var tryCountAsString = eventData.Properties.GetOrDefault(TryCountPropertyName);
+ if (tryCountAsString.IsNullOrEmpty())
+ {
+ return 0;
+ }
+
+ return int.Parse(tryCountAsString);
+ }
+
+ private static void SetEventTryCount(EtoBase eventData, int count)
+ {
+ eventData.Properties[TryCountPropertyName] = count.ToString();
+ }
+
+ private static int IncrementEventTryCount(EtoBase eventData)
+ {
+ var count = GetEventTryCount(eventData) + 1;
+ SetEventTryCount(eventData, count);
+ return count;
+ }
+}
\ No newline at end of file
diff --git a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/Migrations/EfCoreRuntimeDatabaseMigratorBase.cs b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/Migrations/EfCoreRuntimeDatabaseMigratorBase.cs
new file mode 100644
index 0000000000..9b9719ff1b
--- /dev/null
+++ b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/Migrations/EfCoreRuntimeDatabaseMigratorBase.cs
@@ -0,0 +1,145 @@
+using System;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
+using Volo.Abp.Data;
+using Volo.Abp.DependencyInjection;
+using Volo.Abp.DistributedLocking;
+using Volo.Abp.EventBus.Distributed;
+using Volo.Abp.MultiTenancy;
+using Volo.Abp.Uow;
+
+namespace Volo.Abp.EntityFrameworkCore.Migrations;
+
+public abstract class EfCoreRuntimeDatabaseMigratorBase : ITransientDependency
+ where TDbContext : DbContext, IEfCoreDbContext
+{
+ protected int MinValueToWaitOnFailure { get; set; } = 5000;
+ protected int MaxValueToWaitOnFailure { get; set; } = 15000;
+
+ protected string DatabaseName { get; }
+
+ ///
+ /// Enabling this might be inefficient if you have many tenants!
+ /// If disabled (default), tenant databases will be seeded only
+ /// if there is a schema migration applied to the host database.
+ /// If enabled, tenant databases will be seeded always on every service startup.
+ ///
+ protected bool AlwaysSeedTenantDatabases { get; set; } = false;
+
+ protected IUnitOfWorkManager UnitOfWorkManager { get; }
+ protected IServiceProvider ServiceProvider { get; }
+ protected ICurrentTenant CurrentTenant { get; }
+ protected IAbpDistributedLock DistributedLock { get; }
+ protected IDistributedEventBus DistributedEventBus { get; }
+ protected ILogger> Logger { get; }
+
+ protected EfCoreRuntimeDatabaseMigratorBase(
+ string databaseName,
+ IUnitOfWorkManager unitOfWorkManager,
+ IServiceProvider serviceProvider,
+ ICurrentTenant currentTenant,
+ IAbpDistributedLock abpDistributedLock,
+ IDistributedEventBus distributedEventBus,
+ ILoggerFactory loggerFactory)
+ {
+ DatabaseName = databaseName;
+ UnitOfWorkManager = unitOfWorkManager;
+ ServiceProvider = serviceProvider;
+ CurrentTenant = currentTenant;
+ DistributedLock = abpDistributedLock;
+ DistributedEventBus = distributedEventBus;
+ Logger = loggerFactory.CreateLogger>();
+ }
+
+ public virtual async Task CheckAndApplyDatabaseMigrationsAsync()
+ {
+ await TryAsync(LockAndApplyDatabaseMigrationsAsync);
+ }
+
+ protected virtual async Task LockAndApplyDatabaseMigrationsAsync()
+ {
+ Logger.LogInformation($"Trying to acquire the distributed lock for database migration: {DatabaseName}.");
+
+ var schemaMigrated = false;
+
+ await using (var handle = await DistributedLock.TryAcquireAsync("DatabaseMigration_" + DatabaseName))
+ {
+ if (handle is null)
+ {
+ Logger.LogInformation($"Distributed lock could not be acquired for database migration: {DatabaseName}. Operation cancelled.");
+ return;
+ }
+
+ Logger.LogInformation($"Distributed lock is acquired for database migration: {DatabaseName}...");
+
+ using (CurrentTenant.Change(null))
+ {
+ // Create database tables if needed
+ using (var uow = UnitOfWorkManager.Begin(requiresNew: true, isTransactional: false))
+ {
+ var dbContext = await ServiceProvider
+ .GetRequiredService>()
+ .GetDbContextAsync();
+
+ var pendingMigrations = await dbContext
+ .Database
+ .GetPendingMigrationsAsync();
+
+ if (pendingMigrations.Any())
+ {
+ await dbContext.Database.MigrateAsync();
+ schemaMigrated = true;
+ }
+
+ await uow.CompleteAsync();
+ }
+ }
+
+ await SeedAsync();
+
+ if (schemaMigrated || AlwaysSeedTenantDatabases)
+ {
+ await DistributedEventBus.PublishAsync(
+ new AppliedDatabaseMigrationsEto
+ {
+ DatabaseName = DatabaseName,
+ TenantId = null
+ }
+ );
+ }
+ }
+
+ Logger.LogInformation($"Distributed lock has been released for database migration: {DatabaseName}...");
+ }
+
+ protected virtual Task SeedAsync()
+ {
+ return Task.CompletedTask;
+ }
+
+ protected virtual async Task TryAsync(Func task, int maxTryCount = 3)
+ {
+ try
+ {
+ await task();
+ }
+ catch (Exception ex)
+ {
+ maxTryCount--;
+
+ if (maxTryCount <= 0)
+ {
+ throw;
+ }
+
+ Logger.LogWarning($"{ex.GetType().Name} has been thrown. The operation will be tried {maxTryCount} times more. Exception:\n{ex.Message}. Stack Trace:\n{ex.StackTrace}");
+
+ await Task.Delay(RandomHelper.GetRandom(MinValueToWaitOnFailure, MaxValueToWaitOnFailure));
+
+ await TryAsync(task, maxTryCount);
+ }
+ }
+}
\ No newline at end of file
diff --git a/framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/Distributed/IncomingEventInfo.cs b/framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/Distributed/IncomingEventInfo.cs
index d28b28e4d6..372e4e3d77 100644
--- a/framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/Distributed/IncomingEventInfo.cs
+++ b/framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/Distributed/IncomingEventInfo.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
using Volo.Abp.Data;
namespace Volo.Abp.EventBus.Distributed;
@@ -40,4 +41,14 @@ public class IncomingEventInfo : IHasExtraProperties
ExtraProperties = new ExtraPropertyDictionary();
this.SetDefaultsForExtraProperties();
}
+
+ public void SetCorrelationId(string correlationId)
+ {
+ ExtraProperties[EventBusConsts.CorrelationIdHeaderName] = correlationId;
+ }
+
+ public string GetCorrelationId()
+ {
+ return ExtraProperties.GetOrDefault(EventBusConsts.CorrelationIdHeaderName)?.ToString();
+ }
}
diff --git a/framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/Distributed/OutgoingEventInfo.cs b/framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/Distributed/OutgoingEventInfo.cs
index 359b33f3b3..299935741e 100644
--- a/framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/Distributed/OutgoingEventInfo.cs
+++ b/framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/Distributed/OutgoingEventInfo.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
using Volo.Abp.Data;
namespace Volo.Abp.EventBus.Distributed;
@@ -36,4 +37,14 @@ public class OutgoingEventInfo : IHasExtraProperties
ExtraProperties = new ExtraPropertyDictionary();
this.SetDefaultsForExtraProperties();
}
-}
\ No newline at end of file
+
+ public void SetCorrelationId(string correlationId)
+ {
+ ExtraProperties[EventBusConsts.CorrelationIdHeaderName] = correlationId;
+ }
+
+ public string GetCorrelationId()
+ {
+ return ExtraProperties.GetOrDefault(EventBusConsts.CorrelationIdHeaderName)?.ToString();
+ }
+}
diff --git a/framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/EventBusConsts.cs b/framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/EventBusConsts.cs
new file mode 100644
index 0000000000..f1fa920670
--- /dev/null
+++ b/framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/EventBusConsts.cs
@@ -0,0 +1,6 @@
+namespace Volo.Abp.EventBus;
+
+public static class EventBusConsts
+{
+ public const string CorrelationIdHeaderName = "X-Correlation-Id";
+}
diff --git a/framework/src/Volo.Abp.EventBus.Azure/Volo/Abp/EventBus/Azure/AzureDistributedEventBus.cs b/framework/src/Volo.Abp.EventBus.Azure/Volo/Abp/EventBus/Azure/AzureDistributedEventBus.cs
index 8279a412a5..d7ca68bee6 100644
--- a/framework/src/Volo.Abp.EventBus.Azure/Volo/Abp/EventBus/Azure/AzureDistributedEventBus.cs
+++ b/framework/src/Volo.Abp.EventBus.Azure/Volo/Abp/EventBus/Azure/AzureDistributedEventBus.cs
@@ -4,6 +4,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Azure.Messaging.ServiceBus;
+using JetBrains.Annotations;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Volo.Abp.DependencyInjection;
@@ -14,6 +15,7 @@ using Volo.Abp.Guids;
using Volo.Abp.MultiTenancy;
using Volo.Abp.Threading;
using Volo.Abp.Timing;
+using Volo.Abp.Tracing;
using Volo.Abp.Uow;
namespace Volo.Abp.EventBus.Azure;
@@ -42,7 +44,8 @@ public class AzureDistributedEventBus : DistributedEventBusBase, ISingletonDepen
IAzureServiceBusMessageConsumerFactory messageConsumerFactory,
IPublisherPool publisherPool,
IEventHandlerInvoker eventHandlerInvoker,
- ILocalEventBus localEventBus)
+ ILocalEventBus localEventBus,
+ ICorrelationIdProvider correlationIdProvider)
: base(serviceScopeFactory,
currentTenant,
unitOfWorkManager,
@@ -50,7 +53,8 @@ public class AzureDistributedEventBus : DistributedEventBusBase, ISingletonDepen
guidGenerator,
clock,
eventHandlerInvoker,
- localEventBus)
+ localEventBus,
+ correlationIdProvider)
{
Options = abpAzureEventBusOptions.Value;
Serializer = serializer;
@@ -86,24 +90,30 @@ public class AzureDistributedEventBus : DistributedEventBusBase, ISingletonDepen
var eventData = Serializer.Deserialize(message.Body.ToArray(), eventType);
- if (await AddToInboxAsync(message.MessageId, eventName, eventType, eventData))
+ if (await AddToInboxAsync(message.MessageId, eventName, eventType, eventData, message.CorrelationId))
{
return;
}
- await TriggerHandlersDirectAsync(eventType, eventData);
+ using (CorrelationIdProvider.Change(message.CorrelationId))
+ {
+ await TriggerHandlersDirectAsync(eventType, eventData);
+ }
}
public async override Task PublishFromOutboxAsync(OutgoingEventInfo outgoingEvent, OutboxConfig outboxConfig)
{
- await TriggerDistributedEventSentAsync(new DistributedEventSent()
+ using (CorrelationIdProvider.Change(outgoingEvent.GetCorrelationId()))
{
- Source = DistributedEventSource.Outbox,
- EventName = outgoingEvent.EventName,
- EventData = outgoingEvent.EventData
- });
+ await TriggerDistributedEventSentAsync(new DistributedEventSent()
+ {
+ Source = DistributedEventSource.Outbox,
+ EventName = outgoingEvent.EventName,
+ EventData = outgoingEvent.EventData
+ });
+ }
- await PublishAsync(outgoingEvent.EventName, outgoingEvent.EventData, outgoingEvent.Id);
+ await PublishAsync(outgoingEvent.EventName, outgoingEvent.EventData, outgoingEvent.GetCorrelationId(), outgoingEvent.Id);
}
public async override Task PublishManyFromOutboxAsync(IEnumerable outgoingEvents, OutboxConfig outboxConfig)
@@ -125,18 +135,23 @@ public class AzureDistributedEventBus : DistributedEventBusBase, ISingletonDepen
message.MessageId = outgoingEvent.Id.ToString();
}
+ message.CorrelationId = outgoingEvent.GetCorrelationId();
+
if (!messageBatch.TryAddMessage(message))
{
throw new AbpException(
"The message is too large to fit in the batch. Set AbpEventBusBoxesOptions.OutboxWaitingEventMaxCount to reduce the number");
}
- await TriggerDistributedEventSentAsync(new DistributedEventSent()
+ using (CorrelationIdProvider.Change(outgoingEvent.GetCorrelationId()))
{
- Source = DistributedEventSource.Outbox,
- EventName = outgoingEvent.EventName,
- EventData = outgoingEvent.EventData
- });
+ await TriggerDistributedEventSentAsync(new DistributedEventSent()
+ {
+ Source = DistributedEventSource.Outbox,
+ EventName = outgoingEvent.EventName,
+ EventData = outgoingEvent.EventData
+ });
+ }
}
await publisher.SendMessagesAsync(messageBatch);
@@ -152,7 +167,10 @@ public class AzureDistributedEventBus : DistributedEventBusBase, ISingletonDepen
var eventData = Serializer.Deserialize(incomingEvent.EventData, eventType);
var exceptions = new List();
- await TriggerHandlersFromInboxAsync(eventType, eventData, exceptions, inboxConfig);
+ using (CorrelationIdProvider.Change(incomingEvent.GetCorrelationId()))
+ {
+ await TriggerHandlersFromInboxAsync(eventType, eventData, exceptions, inboxConfig);
+ }
if (exceptions.Any())
{
ThrowOriginalExceptions(eventType, exceptions);
@@ -244,12 +262,13 @@ public class AzureDistributedEventBus : DistributedEventBusBase, ISingletonDepen
{
var body = Serializer.Serialize(eventData);
- return PublishAsync(eventName, body, null);
+ return PublishAsync(eventName, body, CorrelationIdProvider.Get(), null);
}
protected virtual async Task PublishAsync(
string eventName,
byte[] body,
+ [CanBeNull] string correlationId,
Guid? eventId)
{
var message = new ServiceBusMessage(body)
@@ -262,6 +281,8 @@ public class AzureDistributedEventBus : DistributedEventBusBase, ISingletonDepen
message.MessageId = (eventId ?? GuidGenerator.Create()).ToString("N");
}
+ message.CorrelationId = correlationId;
+
var publisher = await PublisherPool.GetAsync(
Options.TopicName,
Options.ConnectionName);
diff --git a/framework/src/Volo.Abp.EventBus.Dapr/Volo/Abp/EventBus/Dapr/AbpDaprEventData.cs b/framework/src/Volo.Abp.EventBus.Dapr/Volo/Abp/EventBus/Dapr/AbpDaprEventData.cs
new file mode 100644
index 0000000000..ee08586b8d
--- /dev/null
+++ b/framework/src/Volo.Abp.EventBus.Dapr/Volo/Abp/EventBus/Dapr/AbpDaprEventData.cs
@@ -0,0 +1,23 @@
+namespace Volo.Abp.EventBus.Dapr;
+
+public class AbpDaprEventData
+{
+ public string PubSubName { get; set; }
+
+ public string Topic { get; set; }
+
+ public string MessageId { get; set; }
+
+ public string JsonData { get; set; }
+
+ public string CorrelationId { get; set; }
+
+ public AbpDaprEventData(string pubSubName, string topic, string messageId, string jsonData, string correlationId)
+ {
+ PubSubName = pubSubName;
+ Topic = topic;
+ MessageId = messageId;
+ JsonData = jsonData;
+ CorrelationId = correlationId;
+ }
+}
diff --git a/framework/src/Volo.Abp.EventBus.Dapr/Volo/Abp/EventBus/Dapr/DaprDistributedEventBus.cs b/framework/src/Volo.Abp.EventBus.Dapr/Volo/Abp/EventBus/Dapr/DaprDistributedEventBus.cs
index 23cf8aa1e9..4912a58388 100644
--- a/framework/src/Volo.Abp.EventBus.Dapr/Volo/Abp/EventBus/Dapr/DaprDistributedEventBus.cs
+++ b/framework/src/Volo.Abp.EventBus.Dapr/Volo/Abp/EventBus/Dapr/DaprDistributedEventBus.cs
@@ -13,6 +13,7 @@ using Volo.Abp.Guids;
using Volo.Abp.MultiTenancy;
using Volo.Abp.Threading;
using Volo.Abp.Timing;
+using Volo.Abp.Tracing;
using Volo.Abp.Uow;
namespace Volo.Abp.EventBus.Dapr;
@@ -39,8 +40,17 @@ public class DaprDistributedEventBus : DistributedEventBusBase, ISingletonDepend
IDaprSerializer serializer,
IOptions daprEventBusOptions,
IAbpDaprClientFactory daprClientFactory,
- ILocalEventBus localEventBus)
- : base(serviceScopeFactory, currentTenant, unitOfWorkManager, abpDistributedEventBusOptions, guidGenerator, clock, eventHandlerInvoker, localEventBus)
+ ILocalEventBus localEventBus,
+ ICorrelationIdProvider correlationIdProvider)
+ : base(serviceScopeFactory,
+ currentTenant,
+ unitOfWorkManager,
+ abpDistributedEventBusOptions,
+ guidGenerator,
+ clock,
+ eventHandlerInvoker,
+ localEventBus,
+ correlationIdProvider)
{
Serializer = serializer;
DaprEventBusOptions = daprEventBusOptions.Value;
@@ -119,9 +129,9 @@ public class DaprDistributedEventBus : DistributedEventBusBase, ISingletonDepend
GetOrCreateHandlerFactories(eventType).Locking(factories => factories.Clear());
}
- protected override async Task PublishToEventBusAsync(Type eventType, object eventData)
+ protected async override Task PublishToEventBusAsync(Type eventType, object eventData)
{
- await PublishToDaprAsync(eventType, eventData);
+ await PublishToDaprAsync(eventType, eventData, null, CorrelationIdProvider.Get());
}
protected override void AddToUnitOfWork(IUnitOfWork unitOfWork, UnitOfWorkEventRecord eventRecord)
@@ -141,43 +151,52 @@ public class DaprDistributedEventBus : DistributedEventBusBase, ISingletonDepend
return handlerFactoryList.ToArray();
}
- public override async Task PublishFromOutboxAsync(OutgoingEventInfo outgoingEvent, OutboxConfig outboxConfig)
+ public async override Task PublishFromOutboxAsync(OutgoingEventInfo outgoingEvent, OutboxConfig outboxConfig)
{
- await TriggerDistributedEventSentAsync(new DistributedEventSent()
+ using (CorrelationIdProvider.Change(outgoingEvent.GetCorrelationId()))
{
- Source = DistributedEventSource.Outbox,
- EventName = outgoingEvent.EventName,
- EventData = outgoingEvent.EventData
- });
+ await TriggerDistributedEventSentAsync(new DistributedEventSent()
+ {
+ Source = DistributedEventSource.Outbox,
+ EventName = outgoingEvent.EventName,
+ EventData = outgoingEvent.EventData
+ });
+ }
- await PublishToDaprAsync(outgoingEvent.EventName, Serializer.Deserialize(outgoingEvent.EventData, GetEventType(outgoingEvent.EventName)));
+ await PublishToDaprAsync(outgoingEvent.EventName, Serializer.Deserialize(outgoingEvent.EventData, GetEventType(outgoingEvent.EventName)), outgoingEvent.Id, outgoingEvent.GetCorrelationId());
}
- public override async Task PublishManyFromOutboxAsync(IEnumerable outgoingEvents, OutboxConfig outboxConfig)
+ public async override Task PublishManyFromOutboxAsync(IEnumerable outgoingEvents, OutboxConfig outboxConfig)
{
var outgoingEventArray = outgoingEvents.ToArray();
foreach (var outgoingEvent in outgoingEventArray)
{
- await TriggerDistributedEventSentAsync(new DistributedEventSent()
+ using (CorrelationIdProvider.Change(outgoingEvent.GetCorrelationId()))
{
- Source = DistributedEventSource.Outbox,
- EventName = outgoingEvent.EventName,
- EventData = outgoingEvent.EventData
- });
+ await TriggerDistributedEventSentAsync(new DistributedEventSent()
+ {
+ Source = DistributedEventSource.Outbox,
+ EventName = outgoingEvent.EventName,
+ EventData = outgoingEvent.EventData
+ });
+ }
- await PublishToDaprAsync(outgoingEvent.EventName, Serializer.Deserialize(outgoingEvent.EventData, GetEventType(outgoingEvent.EventName)));
+ await PublishToDaprAsync(outgoingEvent.EventName, Serializer.Deserialize(outgoingEvent.EventData, GetEventType(outgoingEvent.EventName)), outgoingEvent.Id, outgoingEvent.GetCorrelationId());
}
}
- public virtual async Task TriggerHandlersAsync(string messageId, Type eventType, object eventData)
+ public virtual async Task TriggerHandlersAsync(Type eventType, object eventData, string messageId = null, string correlationId = null)
{
- if (await AddToInboxAsync(messageId, EventNameAttribute.GetNameOrDefault(eventType), eventType, eventData))
+ if (await AddToInboxAsync(messageId, EventNameAttribute.GetNameOrDefault(eventType), eventType, eventData, correlationId))
{
return;
}
- await TriggerHandlersDirectAsync(eventType, eventData);
+ using (CorrelationIdProvider.Change(correlationId))
+ {
+ await TriggerHandlersDirectAsync(eventType, eventData);
+ }
}
public async override Task ProcessFromInboxAsync(IncomingEventInfo incomingEvent, InboxConfig inboxConfig)
@@ -190,7 +209,10 @@ public class DaprDistributedEventBus : DistributedEventBusBase, ISingletonDepend
var eventData = Serializer.Deserialize(incomingEvent.EventData, eventType);
var exceptions = new List();
- await TriggerHandlersFromInboxAsync(eventType, eventData, exceptions, inboxConfig);
+ using (CorrelationIdProvider.Change(incomingEvent.GetCorrelationId()))
+ {
+ await TriggerHandlersFromInboxAsync(eventType, eventData, exceptions, inboxConfig);
+ }
if (exceptions.Any())
{
ThrowOriginalExceptions(eventType, exceptions);
@@ -226,15 +248,16 @@ public class DaprDistributedEventBus : DistributedEventBusBase, ISingletonDepend
return EventTypes.GetOrDefault(eventName);
}
- protected virtual async Task PublishToDaprAsync(Type eventType, object eventData)
+ protected virtual async Task PublishToDaprAsync(Type eventType, object eventData, Guid? messageId = null, string correlationId = null)
{
- await PublishToDaprAsync(EventNameAttribute.GetNameOrDefault(eventType), eventData);
+ await PublishToDaprAsync(EventNameAttribute.GetNameOrDefault(eventType), eventData, messageId, correlationId);
}
- protected virtual async Task PublishToDaprAsync(string eventName, object eventData)
+ protected virtual async Task PublishToDaprAsync(string eventName, object eventData, Guid? messageId = null, string correlationId = null)
{
var client = DaprClientFactory.Create();
- await client.PublishEventAsync(pubsubName: DaprEventBusOptions.PubSubName, topicName: eventName, data: eventData);
+ var data = new AbpDaprEventData(DaprEventBusOptions.PubSubName, eventName, (messageId ?? GuidGenerator.Create()).ToString("N"), Serializer.SerializeToString(eventData), correlationId);
+ await client.PublishEventAsync(pubsubName: DaprEventBusOptions.PubSubName, topicName: eventName, data: data);
}
private static bool ShouldTriggerEventForHandler(Type targetEventType, Type handlerEventType)
diff --git a/framework/src/Volo.Abp.EventBus.Kafka/Volo/Abp/EventBus/Kafka/KafkaDistributedEventBus.cs b/framework/src/Volo.Abp.EventBus.Kafka/Volo/Abp/EventBus/Kafka/KafkaDistributedEventBus.cs
index 62e161fad1..b49ffc07a9 100644
--- a/framework/src/Volo.Abp.EventBus.Kafka/Volo/Abp/EventBus/Kafka/KafkaDistributedEventBus.cs
+++ b/framework/src/Volo.Abp.EventBus.Kafka/Volo/Abp/EventBus/Kafka/KafkaDistributedEventBus.cs
@@ -14,6 +14,7 @@ using Volo.Abp.Kafka;
using Volo.Abp.MultiTenancy;
using Volo.Abp.Threading;
using Volo.Abp.Timing;
+using Volo.Abp.Tracing;
using Volo.Abp.Uow;
namespace Volo.Abp.EventBus.Kafka;
@@ -42,7 +43,8 @@ public class KafkaDistributedEventBus : DistributedEventBusBase, ISingletonDepen
IGuidGenerator guidGenerator,
IClock clock,
IEventHandlerInvoker eventHandlerInvoker,
- ILocalEventBus localEventBus)
+ ILocalEventBus localEventBus,
+ ICorrelationIdProvider correlationIdProvider)
: base(
serviceScopeFactory,
currentTenant,
@@ -51,7 +53,8 @@ public class KafkaDistributedEventBus : DistributedEventBusBase, ISingletonDepen
guidGenerator,
clock,
eventHandlerInvoker,
- localEventBus)
+ localEventBus,
+ correlationIdProvider)
{
AbpKafkaEventBusOptions = abpKafkaEventBusOptions.Value;
MessageConsumerFactory = messageConsumerFactory;
@@ -84,13 +87,17 @@ public class KafkaDistributedEventBus : DistributedEventBusBase, ISingletonDepen
var messageId = message.GetMessageId();
var eventData = Serializer.Deserialize(message.Value, eventType);
+ var correlationId = message.GetCorrelationId();
- if (await AddToInboxAsync(messageId, eventName, eventType, eventData))
+ if (await AddToInboxAsync(messageId, eventName, eventType, eventData, correlationId))
{
return;
}
- await TriggerHandlersDirectAsync(eventType, eventData);
+ using (CorrelationIdProvider.Change(correlationId))
+ {
+ await TriggerHandlersDirectAsync(eventType, eventData);
+ }
}
public override IDisposable Subscribe(Type eventType, IEventHandlerFactory factory)
@@ -163,14 +170,21 @@ public class KafkaDistributedEventBus : DistributedEventBusBase, ISingletonDepen
protected async override Task PublishToEventBusAsync(Type eventType, object eventData)
{
+ var headers = new Headers
+ {
+ { "messageId", System.Text.Encoding.UTF8.GetBytes(Guid.NewGuid().ToString("N")) }
+ };
+
+ if (CorrelationIdProvider.Get() != null)
+ {
+ headers.Add(EventBusConsts.CorrelationIdHeaderName, System.Text.Encoding.UTF8.GetBytes(CorrelationIdProvider.Get()!));
+ }
+
await PublishAsync(
AbpKafkaEventBusOptions.TopicName,
eventType,
eventData,
- new Headers
- {
- { "messageId", System.Text.Encoding.UTF8.GetBytes(Guid.NewGuid().ToString("N")) }
- }
+ headers
);
}
@@ -179,25 +193,34 @@ public class KafkaDistributedEventBus : DistributedEventBusBase, ISingletonDepen
unitOfWork.AddOrReplaceDistributedEvent(eventRecord);
}
- public override async Task PublishFromOutboxAsync(
+ public async override Task PublishFromOutboxAsync(
OutgoingEventInfo outgoingEvent,
OutboxConfig outboxConfig)
{
- await TriggerDistributedEventSentAsync(new DistributedEventSent()
+ using (CorrelationIdProvider.Change(outgoingEvent.GetCorrelationId()))
{
- Source = DistributedEventSource.Outbox,
- EventName = outgoingEvent.EventName,
- EventData = outgoingEvent.EventData
- });
+ await TriggerDistributedEventSentAsync(new DistributedEventSent()
+ {
+ Source = DistributedEventSource.Outbox,
+ EventName = outgoingEvent.EventName,
+ EventData = outgoingEvent.EventData
+ });
+ }
+
+ var headers = new Headers
+ {
+ { "messageId", System.Text.Encoding.UTF8.GetBytes(outgoingEvent.Id.ToString("N")) }
+ };
+ if (outgoingEvent.GetCorrelationId() != null)
+ {
+ headers.Add(EventBusConsts.CorrelationIdHeaderName, System.Text.Encoding.UTF8.GetBytes(outgoingEvent.GetCorrelationId()!));
+ }
await PublishAsync(
AbpKafkaEventBusOptions.TopicName,
outgoingEvent.EventName,
outgoingEvent.EventData,
- new Headers
- {
- { "messageId", System.Text.Encoding.UTF8.GetBytes(outgoingEvent.Id.ToString("N")) }
- }
+ headers
);
}
@@ -214,12 +237,20 @@ public class KafkaDistributedEventBus : DistributedEventBusBase, ISingletonDepen
{ "messageId", System.Text.Encoding.UTF8.GetBytes(messageId)}
};
- await TriggerDistributedEventSentAsync(new DistributedEventSent()
+ if (outgoingEvent.GetCorrelationId() != null)
{
- Source = DistributedEventSource.Outbox,
- EventName = outgoingEvent.EventName,
- EventData = outgoingEvent.EventData
- });
+ headers.Add(EventBusConsts.CorrelationIdHeaderName, System.Text.Encoding.UTF8.GetBytes(outgoingEvent.GetCorrelationId()!));
+ }
+
+ using (CorrelationIdProvider.Change(outgoingEvent.GetCorrelationId()))
+ {
+ await TriggerDistributedEventSentAsync(new DistributedEventSent()
+ {
+ Source = DistributedEventSource.Outbox,
+ EventName = outgoingEvent.EventName,
+ EventData = outgoingEvent.EventData
+ });
+ }
producer.Produce(
AbpKafkaEventBusOptions.TopicName,
@@ -244,7 +275,10 @@ public class KafkaDistributedEventBus : DistributedEventBusBase, ISingletonDepen
var eventData = Serializer.Deserialize(incomingEvent.EventData, eventType);
var exceptions = new List();
- await TriggerHandlersFromInboxAsync(eventType, eventData, exceptions, inboxConfig);
+ using (CorrelationIdProvider.Change(incomingEvent.GetCorrelationId()))
+ {
+ await TriggerHandlersFromInboxAsync(eventType, eventData, exceptions, inboxConfig);
+ }
if (exceptions.Any())
{
ThrowOriginalExceptions(eventType, exceptions);
diff --git a/framework/src/Volo.Abp.EventBus.Kafka/Volo/Abp/EventBus/Kafka/MessageExtensions.cs b/framework/src/Volo.Abp.EventBus.Kafka/Volo/Abp/EventBus/Kafka/MessageExtensions.cs
index 17a80ec87c..569e56a1dc 100644
--- a/framework/src/Volo.Abp.EventBus.Kafka/Volo/Abp/EventBus/Kafka/MessageExtensions.cs
+++ b/framework/src/Volo.Abp.EventBus.Kafka/Volo/Abp/EventBus/Kafka/MessageExtensions.cs
@@ -15,4 +15,16 @@ public static class MessageExtensions
return messageId;
}
+
+ public static string GetCorrelationId(this Message message)
+ {
+ string correlationId = null;
+
+ if (message.Headers.TryGetLastBytes(EventBusConsts.CorrelationIdHeaderName, out var correlationIdBytes))
+ {
+ correlationId = System.Text.Encoding.UTF8.GetString(correlationIdBytes);
+ }
+
+ return correlationId;
+ }
}
diff --git a/framework/src/Volo.Abp.EventBus.RabbitMQ/Volo/Abp/EventBus/RabbitMq/RabbitMqDistributedEventBus.cs b/framework/src/Volo.Abp.EventBus.RabbitMQ/Volo/Abp/EventBus/RabbitMq/RabbitMqDistributedEventBus.cs
index 8d4756165a..a2459ea8d4 100644
--- a/framework/src/Volo.Abp.EventBus.RabbitMQ/Volo/Abp/EventBus/RabbitMq/RabbitMqDistributedEventBus.cs
+++ b/framework/src/Volo.Abp.EventBus.RabbitMQ/Volo/Abp/EventBus/RabbitMq/RabbitMqDistributedEventBus.cs
@@ -3,6 +3,7 @@ using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
+using JetBrains.Annotations;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using RabbitMQ.Client;
@@ -15,6 +16,7 @@ using Volo.Abp.MultiTenancy;
using Volo.Abp.RabbitMQ;
using Volo.Abp.Threading;
using Volo.Abp.Timing;
+using Volo.Abp.Tracing;
using Volo.Abp.Uow;
namespace Volo.Abp.EventBus.RabbitMq;
@@ -49,7 +51,8 @@ public class RabbitMqDistributedEventBus : DistributedEventBusBase, ISingletonDe
IGuidGenerator guidGenerator,
IClock clock,
IEventHandlerInvoker eventHandlerInvoker,
- ILocalEventBus localEventBus)
+ ILocalEventBus localEventBus,
+ ICorrelationIdProvider correlationIdProvider)
: base(
serviceScopeFactory,
currentTenant,
@@ -58,7 +61,8 @@ public class RabbitMqDistributedEventBus : DistributedEventBusBase, ISingletonDe
guidGenerator,
clock,
eventHandlerInvoker,
- localEventBus)
+ localEventBus,
+ correlationIdProvider)
{
ConnectionPool = connectionPool;
Serializer = serializer;
@@ -103,12 +107,16 @@ public class RabbitMqDistributedEventBus : DistributedEventBusBase, ISingletonDe
var eventData = Serializer.Deserialize(ea.Body.ToArray(), eventType);
- if (await AddToInboxAsync(ea.BasicProperties.MessageId, eventName, eventType, eventData))
+ var correlationId = ea.BasicProperties.CorrelationId;
+ if (await AddToInboxAsync(ea.BasicProperties.MessageId, eventName, eventType, eventData, correlationId))
{
return;
}
- await TriggerHandlersDirectAsync(eventType, eventData);
+ using (CorrelationIdProvider.Change(correlationId))
+ {
+ await TriggerHandlersDirectAsync(eventType, eventData);
+ }
}
public override IDisposable Subscribe(Type eventType, IEventHandlerFactory factory)
@@ -186,7 +194,7 @@ public class RabbitMqDistributedEventBus : DistributedEventBusBase, ISingletonDe
protected async override Task PublishToEventBusAsync(Type eventType, object eventData)
{
- await PublishAsync(eventType, eventData, null);
+ await PublishAsync(eventType, eventData, correlationId: CorrelationIdProvider.Get());
}
protected override void AddToUnitOfWork(IUnitOfWork unitOfWork, UnitOfWorkEventRecord eventRecord)
@@ -194,18 +202,21 @@ public class RabbitMqDistributedEventBus : DistributedEventBusBase, ISingletonDe
unitOfWork.AddOrReplaceDistributedEvent(eventRecord);
}
- public override async Task PublishFromOutboxAsync(
+ public async override Task PublishFromOutboxAsync(
OutgoingEventInfo outgoingEvent,
OutboxConfig outboxConfig)
{
- await TriggerDistributedEventSentAsync(new DistributedEventSent()
+ using (CorrelationIdProvider.Change(outgoingEvent.GetCorrelationId()))
{
- Source = DistributedEventSource.Outbox,
- EventName = outgoingEvent.EventName,
- EventData = outgoingEvent.EventData
- });
+ await TriggerDistributedEventSentAsync(new DistributedEventSent()
+ {
+ Source = DistributedEventSource.Outbox,
+ EventName = outgoingEvent.EventName,
+ EventData = outgoingEvent.EventData
+ });
+ }
- await PublishAsync(outgoingEvent.EventName, outgoingEvent.EventData, null, eventId: outgoingEvent.Id);
+ await PublishAsync(outgoingEvent.EventName, outgoingEvent.EventData, eventId: outgoingEvent.Id, correlationId: outgoingEvent.GetCorrelationId());
}
public async override Task PublishManyFromOutboxAsync(
@@ -219,19 +230,22 @@ public class RabbitMqDistributedEventBus : DistributedEventBusBase, ISingletonDe
foreach (var outgoingEvent in outgoingEventArray)
{
- await TriggerDistributedEventSentAsync(new DistributedEventSent()
+ using (CorrelationIdProvider.Change(outgoingEvent.GetCorrelationId()))
{
- Source = DistributedEventSource.Outbox,
- EventName = outgoingEvent.EventName,
- EventData = outgoingEvent.EventData
- });
+ await TriggerDistributedEventSentAsync(new DistributedEventSent()
+ {
+ Source = DistributedEventSource.Outbox,
+ EventName = outgoingEvent.EventName,
+ EventData = outgoingEvent.EventData
+ });
+ }
await PublishAsync(
channel,
outgoingEvent.EventName,
outgoingEvent.EventData,
- properties: null,
- eventId: outgoingEvent.Id);
+ eventId: outgoingEvent.Id,
+ correlationId: outgoingEvent.GetCorrelationId());
}
channel.WaitForConfirmsOrDie();
@@ -250,7 +264,10 @@ public class RabbitMqDistributedEventBus : DistributedEventBusBase, ISingletonDe
var eventData = Serializer.Deserialize(incomingEvent.EventData, eventType);
var exceptions = new List();
- await TriggerHandlersFromInboxAsync(eventType, eventData, exceptions, inboxConfig);
+ using (CorrelationIdProvider.Change(incomingEvent.GetCorrelationId()))
+ {
+ await TriggerHandlersFromInboxAsync(eventType, eventData, exceptions, inboxConfig);
+ }
if (exceptions.Any())
{
ThrowOriginalExceptions(eventType, exceptions);
@@ -262,28 +279,29 @@ public class RabbitMqDistributedEventBus : DistributedEventBusBase, ISingletonDe
return Serializer.Serialize(eventData);
}
- public Task PublishAsync(
+ public virtual Task PublishAsync(
Type eventType,
object eventData,
- IBasicProperties properties,
- Dictionary headersArguments = null)
+ Dictionary headersArguments = null,
+ Guid? eventId = null,
+ [CanBeNull] string correlationId = null)
{
var eventName = EventNameAttribute.GetNameOrDefault(eventType);
var body = Serializer.Serialize(eventData);
- return PublishAsync(eventName, body, properties, headersArguments);
+ return PublishAsync( eventName, body, headersArguments, eventId, correlationId);
}
protected virtual Task PublishAsync(
string eventName,
byte[] body,
- IBasicProperties properties,
Dictionary headersArguments = null,
- Guid? eventId = null)
+ Guid? eventId = null,
+ [CanBeNull] string correlationId = null)
{
using (var channel = ConnectionPool.Get(AbpRabbitMqEventBusOptions.ConnectionName).CreateModel())
{
- return PublishAsync(channel, eventName, body, properties, headersArguments, eventId);
+ return PublishAsync(channel, eventName, body, headersArguments, eventId, correlationId);
}
}
@@ -291,23 +309,25 @@ public class RabbitMqDistributedEventBus : DistributedEventBusBase, ISingletonDe
IModel channel,
string eventName,
byte[] body,
- IBasicProperties properties,
Dictionary headersArguments = null,
- Guid? eventId = null)
+ Guid? eventId = null,
+ [CanBeNull] string correlationId = null)
{
EnsureExchangeExists(channel);
- if (properties == null)
- {
- properties = channel.CreateBasicProperties();
- properties.DeliveryMode = RabbitMqConsts.DeliveryModes.Persistent;
- }
+ var properties = channel.CreateBasicProperties();
+ properties.DeliveryMode = RabbitMqConsts.DeliveryModes.Persistent;
if (properties.MessageId.IsNullOrEmpty())
{
properties.MessageId = (eventId ?? GuidGenerator.Create()).ToString("N");
}
+ if (correlationId != null)
+ {
+ properties.CorrelationId = correlationId;
+ }
+
SetEventMessageHeaders(properties, headersArguments);
channel.BasicPublish(
diff --git a/framework/src/Volo.Abp.EventBus.Rebus/Volo/Abp/EventBus/Rebus/RebusDistributedEventBus.cs b/framework/src/Volo.Abp.EventBus.Rebus/Volo/Abp/EventBus/Rebus/RebusDistributedEventBus.cs
index 0983e98836..560b13ba14 100644
--- a/framework/src/Volo.Abp.EventBus.Rebus/Volo/Abp/EventBus/Rebus/RebusDistributedEventBus.cs
+++ b/framework/src/Volo.Abp.EventBus.Rebus/Volo/Abp/EventBus/Rebus/RebusDistributedEventBus.cs
@@ -16,6 +16,7 @@ using Volo.Abp.Guids;
using Volo.Abp.MultiTenancy;
using Volo.Abp.Threading;
using Volo.Abp.Timing;
+using Volo.Abp.Tracing;
using Volo.Abp.Uow;
namespace Volo.Abp.EventBus.Rebus;
@@ -43,7 +44,8 @@ public class RebusDistributedEventBus : DistributedEventBusBase, ISingletonDepen
IGuidGenerator guidGenerator,
IClock clock,
IEventHandlerInvoker eventHandlerInvoker,
- ILocalEventBus localEventBus) :
+ ILocalEventBus localEventBus,
+ ICorrelationIdProvider correlationIdProvider) :
base(
serviceScopeFactory,
currentTenant,
@@ -52,7 +54,8 @@ public class RebusDistributedEventBus : DistributedEventBusBase, ISingletonDepen
guidGenerator,
clock,
eventHandlerInvoker,
- localEventBus)
+ localEventBus,
+ correlationIdProvider)
{
Rebus = rebus;
Serializer = serializer;
@@ -144,18 +147,27 @@ public class RebusDistributedEventBus : DistributedEventBusBase, ISingletonDepen
{
var messageId = MessageContext.Current.TransportMessage.GetMessageId();
var eventName = EventNameAttribute.GetNameOrDefault(eventType);
+ var correlationId = MessageContext.Current.Headers.GetOrDefault(EventBusConsts.CorrelationIdHeaderName);
- if (await AddToInboxAsync(messageId, eventName, eventType, eventData))
+ if (await AddToInboxAsync(messageId, eventName, eventType, eventData, correlationId))
{
return;
}
- await TriggerHandlersDirectAsync(eventType, eventData);
+ using (CorrelationIdProvider.Change(correlationId))
+ {
+ await TriggerHandlersDirectAsync(eventType, eventData);
+ }
}
protected async override Task PublishToEventBusAsync(Type eventType, object eventData)
{
- await PublishAsync(eventType, eventData);
+ var headers = new Dictionary();
+ if (CorrelationIdProvider.Get() != null)
+ {
+ headers.Add(EventBusConsts.CorrelationIdHeaderName, CorrelationIdProvider.Get());
+ }
+ await PublishAsync(eventType, eventData, headersArguments: headers);
}
protected virtual async Task PublishAsync(
@@ -234,21 +246,29 @@ public class RebusDistributedEventBus : DistributedEventBusBase, ISingletonDepen
return false;
}
- public override async Task PublishFromOutboxAsync(
+ public async override Task PublishFromOutboxAsync(
OutgoingEventInfo outgoingEvent,
OutboxConfig outboxConfig)
{
var eventType = EventTypes.GetOrDefault(outgoingEvent.EventName);
var eventData = Serializer.Deserialize(outgoingEvent.EventData, eventType);
- await TriggerDistributedEventSentAsync(new DistributedEventSent()
+ using (CorrelationIdProvider.Change(outgoingEvent.GetCorrelationId()))
{
- Source = DistributedEventSource.Outbox,
- EventName = outgoingEvent.EventName,
- EventData = outgoingEvent.EventData
- });
+ await TriggerDistributedEventSentAsync(new DistributedEventSent() {
+ Source = DistributedEventSource.Outbox,
+ EventName = outgoingEvent.EventName,
+ EventData = outgoingEvent.EventData
+ });
+ }
- await PublishAsync(eventType, eventData, eventId: outgoingEvent.Id);
+ var headers = new Dictionary();
+ if (outgoingEvent.GetCorrelationId() != null)
+ {
+ headers.Add(EventBusConsts.CorrelationIdHeaderName, outgoingEvent.GetCorrelationId());
+ }
+
+ await PublishAsync(eventType, eventData, eventId: outgoingEvent.Id, headersArguments: headers);
}
public async override Task PublishManyFromOutboxAsync(IEnumerable outgoingEvents, OutboxConfig outboxConfig)
@@ -259,12 +279,15 @@ public class RebusDistributedEventBus : DistributedEventBusBase, ISingletonDepen
{
foreach (var outgoingEvent in outgoingEventArray)
{
- await TriggerDistributedEventSentAsync(new DistributedEventSent()
+ using (CorrelationIdProvider.Change(outgoingEvent.GetCorrelationId()))
{
- Source = DistributedEventSource.Outbox,
- EventName = outgoingEvent.EventName,
- EventData = outgoingEvent.EventData
- });
+ await TriggerDistributedEventSentAsync(new DistributedEventSent()
+ {
+ Source = DistributedEventSource.Outbox,
+ EventName = outgoingEvent.EventName,
+ EventData = outgoingEvent.EventData
+ });
+ }
await PublishFromOutboxAsync(outgoingEvent, outboxConfig);
}
@@ -285,7 +308,10 @@ public class RebusDistributedEventBus : DistributedEventBusBase, ISingletonDepen
var eventData = Serializer.Deserialize(incomingEvent.EventData, eventType);
var exceptions = new List();
- await TriggerHandlersFromInboxAsync(eventType, eventData, exceptions, inboxConfig);
+ using (CorrelationIdProvider.Change(incomingEvent.GetCorrelationId()))
+ {
+ await TriggerHandlersFromInboxAsync(eventType, eventData, exceptions, inboxConfig);
+ }
if (exceptions.Any())
{
ThrowOriginalExceptions(eventType, exceptions);
diff --git a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/DistributedEventBusBase.cs b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/DistributedEventBusBase.cs
index 89423ce111..2ca5c85bb0 100644
--- a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/DistributedEventBusBase.cs
+++ b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/DistributedEventBusBase.cs
@@ -2,12 +2,14 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
+using JetBrains.Annotations;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Volo.Abp.EventBus.Local;
using Volo.Abp.Guids;
using Volo.Abp.MultiTenancy;
using Volo.Abp.Timing;
+using Volo.Abp.Tracing;
using Volo.Abp.Uow;
namespace Volo.Abp.EventBus.Distributed;
@@ -18,6 +20,7 @@ public abstract class DistributedEventBusBase : EventBusBase, IDistributedEventB
protected IClock Clock { get; }
protected AbpDistributedEventBusOptions AbpDistributedEventBusOptions { get; }
protected ILocalEventBus LocalEventBus { get; }
+ protected ICorrelationIdProvider CorrelationIdProvider { get; }
protected DistributedEventBusBase(
IServiceScopeFactory serviceScopeFactory,
@@ -27,7 +30,8 @@ public abstract class DistributedEventBusBase : EventBusBase, IDistributedEventB
IGuidGenerator guidGenerator,
IClock clock,
IEventHandlerInvoker eventHandlerInvoker,
- ILocalEventBus localEventBus) : base(
+ ILocalEventBus localEventBus,
+ ICorrelationIdProvider correlationIdProvider) : base(
serviceScopeFactory,
currentTenant,
unitOfWorkManager,
@@ -37,6 +41,7 @@ public abstract class DistributedEventBusBase : EventBusBase, IDistributedEventB
Clock = clock;
AbpDistributedEventBusOptions = abpDistributedEventBusOptions.Value;
LocalEventBus = localEventBus;
+ CorrelationIdProvider = correlationIdProvider;
}
public IDisposable Subscribe(IDistributedEventHandler handler) where TEvent : class
@@ -129,14 +134,14 @@ public abstract class DistributedEventBusBase : EventBusBase, IDistributedEventB
EventData = eventData
});
- await eventOutbox.EnqueueAsync(
- new OutgoingEventInfo(
- GuidGenerator.Create(),
- eventName,
- Serialize(eventData),
- Clock.Now
- )
+ var outgoingEventInfo = new OutgoingEventInfo(
+ GuidGenerator.Create(),
+ eventName,
+ Serialize(eventData),
+ Clock.Now
);
+ outgoingEventInfo.SetCorrelationId(CorrelationIdProvider.Get());
+ await eventOutbox.EnqueueAsync(outgoingEventInfo);
return true;
}
}
@@ -153,7 +158,8 @@ public abstract class DistributedEventBusBase : EventBusBase, IDistributedEventB
string messageId,
string eventName,
Type eventType,
- object eventData)
+ object eventData,
+ [CanBeNull] string correlationId)
{
if (AbpDistributedEventBusOptions.Inboxes.Count <= 0)
{
@@ -177,22 +183,25 @@ public abstract class DistributedEventBusBase : EventBusBase, IDistributedEventB
}
}
- await TriggerDistributedEventReceivedAsync(new DistributedEventReceived
+ using (CorrelationIdProvider.Change(correlationId))
{
- Source = DistributedEventSource.Direct,
- EventName = EventNameAttribute.GetNameOrDefault(eventType),
- EventData = eventData
- });
-
- await eventInbox.EnqueueAsync(
- new IncomingEventInfo(
- GuidGenerator.Create(),
- messageId,
- eventName,
- Serialize(eventData),
- Clock.Now
- )
+ await TriggerDistributedEventReceivedAsync(new DistributedEventReceived
+ {
+ Source = DistributedEventSource.Direct,
+ EventName = EventNameAttribute.GetNameOrDefault(eventType),
+ EventData = eventData
+ });
+ }
+
+ var incomingEventInfo = new IncomingEventInfo(
+ GuidGenerator.Create(),
+ messageId,
+ eventName,
+ Serialize(eventData),
+ Clock.Now
);
+ incomingEventInfo.SetCorrelationId(correlationId);
+ await eventInbox.EnqueueAsync(incomingEventInfo);
}
}
}
diff --git a/framework/src/Volo.Abp.ExceptionHandling/Volo.Abp.ExceptionHandling.csproj b/framework/src/Volo.Abp.ExceptionHandling/Volo.Abp.ExceptionHandling.csproj
index 7e3061e8c7..de9dc60c0d 100644
--- a/framework/src/Volo.Abp.ExceptionHandling/Volo.Abp.ExceptionHandling.csproj
+++ b/framework/src/Volo.Abp.ExceptionHandling/Volo.Abp.ExceptionHandling.csproj
@@ -5,6 +5,8 @@
netstandard2.0;netstandard2.1;net7.0
+ enable
+ Nullable
true
diff --git a/framework/src/Volo.Abp.ExceptionHandling/Volo/Abp/AspNetCore/ExceptionHandling/DefaultExceptionToErrorInfoConverter.cs b/framework/src/Volo.Abp.ExceptionHandling/Volo/Abp/AspNetCore/ExceptionHandling/DefaultExceptionToErrorInfoConverter.cs
index 1b8742af81..b068890b97 100644
--- a/framework/src/Volo.Abp.ExceptionHandling/Volo/Abp/AspNetCore/ExceptionHandling/DefaultExceptionToErrorInfoConverter.cs
+++ b/framework/src/Volo.Abp.ExceptionHandling/Volo/Abp/AspNetCore/ExceptionHandling/DefaultExceptionToErrorInfoConverter.cs
@@ -54,7 +54,7 @@ public class DefaultExceptionToErrorInfoConverter : IExceptionToErrorInfoConvert
return errorInfo;
}
- public RemoteServiceErrorInfo Convert(Exception exception, Action options = null)
+ public RemoteServiceErrorInfo Convert(Exception exception, Action? options = null)
{
var exceptionHandlingOptions = CreateDefaultOptions();
options?.Invoke(exceptionHandlingOptions);
@@ -90,7 +90,7 @@ public class DefaultExceptionToErrorInfoConverter : IExceptionToErrorInfoConvert
if (exception is EntityNotFoundException)
{
- return CreateEntityNotFoundError(exception as EntityNotFoundException);
+ return CreateEntityNotFoundError((exception as EntityNotFoundException)!);
}
var errorInfo = new RemoteServiceErrorInfo();
@@ -110,10 +110,10 @@ public class DefaultExceptionToErrorInfoConverter : IExceptionToErrorInfoConvert
if (errorInfo.Details.IsNullOrEmpty())
{
- errorInfo.Details = GetValidationErrorNarrative(exception as IHasValidationErrors);
+ errorInfo.Details = GetValidationErrorNarrative((exception as IHasValidationErrors)!);
}
- errorInfo.ValidationErrors = GetValidationErrorInfos(exception as IHasValidationErrors);
+ errorInfo.ValidationErrors = GetValidationErrorInfos((exception as IHasValidationErrors)!);
}
TryToLocalizeExceptionMessage(exception, errorInfo);
@@ -146,7 +146,7 @@ public class DefaultExceptionToErrorInfoConverter : IExceptionToErrorInfoConvert
}
if (exceptionWithErrorCode.Code.IsNullOrWhiteSpace() ||
- !exceptionWithErrorCode.Code.Contains(":"))
+ !exceptionWithErrorCode.Code!.Contains(":"))
{
return;
}
@@ -197,10 +197,8 @@ public class DefaultExceptionToErrorInfoConverter : IExceptionToErrorInfoConvert
protected virtual Exception TryToGetActualException(Exception exception)
{
- if (exception is AggregateException && exception.InnerException != null)
+ if (exception is AggregateException aggException && aggException.InnerException != null)
{
- var aggException = exception as AggregateException;
-
if (aggException.InnerException is AbpValidationException ||
aggException.InnerException is AbpAuthorizationException ||
aggException.InnerException is EntityNotFoundException ||
@@ -223,7 +221,7 @@ public class DefaultExceptionToErrorInfoConverter : IExceptionToErrorInfoConvert
if (exception is AbpValidationException)
{
- errorInfo.ValidationErrors = GetValidationErrorInfos(exception as AbpValidationException);
+ errorInfo.ValidationErrors = GetValidationErrorInfos((exception as AbpValidationException)!);
}
return errorInfo;
@@ -246,9 +244,8 @@ public class DefaultExceptionToErrorInfoConverter : IExceptionToErrorInfoConvert
}
//Additional info for AbpValidationException
- if (exception is AbpValidationException)
+ if (exception is AbpValidationException validationException)
{
- var validationException = exception as AbpValidationException;
if (validationException.ValidationErrors.Count > 0)
{
detailBuilder.AppendLine(GetValidationErrorNarrative(validationException));
@@ -268,9 +265,8 @@ public class DefaultExceptionToErrorInfoConverter : IExceptionToErrorInfoConvert
}
//Inner exceptions for AggregateException
- if (exception is AggregateException)
+ if (exception is AggregateException aggException)
{
- var aggException = exception as AggregateException;
if (aggException.InnerExceptions.IsNullOrEmpty())
{
return;
@@ -289,7 +285,7 @@ public class DefaultExceptionToErrorInfoConverter : IExceptionToErrorInfoConvert
foreach (var validationResult in validationException.ValidationErrors)
{
- var validationError = new RemoteServiceValidationErrorInfo(validationResult.ErrorMessage);
+ var validationError = new RemoteServiceValidationErrorInfo(validationResult.ErrorMessage!);
if (validationResult.MemberNames != null && validationResult.MemberNames.Any())
{
diff --git a/framework/src/Volo.Abp.ExceptionHandling/Volo/Abp/AspNetCore/ExceptionHandling/IExceptionToErrorInfoConverter.cs b/framework/src/Volo.Abp.ExceptionHandling/Volo/Abp/AspNetCore/ExceptionHandling/IExceptionToErrorInfoConverter.cs
index ebf8993bd6..bd14010db0 100644
--- a/framework/src/Volo.Abp.ExceptionHandling/Volo/Abp/AspNetCore/ExceptionHandling/IExceptionToErrorInfoConverter.cs
+++ b/framework/src/Volo.Abp.ExceptionHandling/Volo/Abp/AspNetCore/ExceptionHandling/IExceptionToErrorInfoConverter.cs
@@ -24,5 +24,5 @@ public interface IExceptionToErrorInfoConverter
/// The exception.
/// Additional options.
/// Error info or null
- RemoteServiceErrorInfo Convert(Exception exception, Action options = null);
+ RemoteServiceErrorInfo Convert(Exception exception, Action? options = null);
}
diff --git a/framework/src/Volo.Abp.ExceptionHandling/Volo/Abp/Domain/Entities/EntityNotFoundException.cs b/framework/src/Volo.Abp.ExceptionHandling/Volo/Abp/Domain/Entities/EntityNotFoundException.cs
index 1feb8c4cbb..5f524f9578 100644
--- a/framework/src/Volo.Abp.ExceptionHandling/Volo/Abp/Domain/Entities/EntityNotFoundException.cs
+++ b/framework/src/Volo.Abp.ExceptionHandling/Volo/Abp/Domain/Entities/EntityNotFoundException.cs
@@ -10,12 +10,12 @@ public class EntityNotFoundException : AbpException
///
/// Type of the entity.
///
- public Type EntityType { get; set; }
+ public Type? EntityType { get; set; }
///
/// Id of the Entity.
///
- public object Id { get; set; }
+ public object? Id { get; set; }
///
/// Creates a new object.
@@ -37,7 +37,7 @@ public class EntityNotFoundException : AbpException
///
/// Creates a new object.
///
- public EntityNotFoundException(Type entityType, object id)
+ public EntityNotFoundException(Type entityType, object? id)
: this(entityType, id, null)
{
@@ -46,7 +46,7 @@ public class EntityNotFoundException : AbpException
///
/// Creates a new object.
///
- public EntityNotFoundException(Type entityType, object id, Exception innerException)
+ public EntityNotFoundException(Type entityType, object? id, Exception? innerException)
: base(
id == null
? $"There is no such an entity given id. Entity type: {entityType.FullName}"
diff --git a/framework/src/Volo.Abp.ExceptionHandling/Volo/Abp/Http/Client/AbpRemoteCallException.cs b/framework/src/Volo.Abp.ExceptionHandling/Volo/Abp/Http/Client/AbpRemoteCallException.cs
index 78c5bff6f9..887c8fb081 100644
--- a/framework/src/Volo.Abp.ExceptionHandling/Volo/Abp/Http/Client/AbpRemoteCallException.cs
+++ b/framework/src/Volo.Abp.ExceptionHandling/Volo/Abp/Http/Client/AbpRemoteCallException.cs
@@ -9,18 +9,18 @@ public class AbpRemoteCallException : AbpException, IHasErrorCode, IHasErrorDeta
{
public int HttpStatusCode { get; set; }
- public string Code => Error?.Code;
+ public string? Code => Error?.Code;
- public string Details => Error?.Details;
+ public string? Details => Error?.Details;
- public RemoteServiceErrorInfo Error { get; set; }
+ public RemoteServiceErrorInfo? Error { get; set; }
public AbpRemoteCallException()
{
}
- public AbpRemoteCallException(string message, Exception innerException = null)
+ public AbpRemoteCallException(string message, Exception? innerException = null)
: base(message, innerException)
{
@@ -32,7 +32,7 @@ public class AbpRemoteCallException : AbpException, IHasErrorCode, IHasErrorDeta
}
- public AbpRemoteCallException(RemoteServiceErrorInfo error, Exception innerException = null)
+ public AbpRemoteCallException(RemoteServiceErrorInfo error, Exception? innerException = null)
: base(error.Message, innerException)
{
Error = error;
diff --git a/framework/src/Volo.Abp.ExceptionHandling/Volo/Abp/Http/RemoteServiceErrorInfo.cs b/framework/src/Volo.Abp.ExceptionHandling/Volo/Abp/Http/RemoteServiceErrorInfo.cs
index 89ed87454a..e61d55e2d3 100644
--- a/framework/src/Volo.Abp.ExceptionHandling/Volo/Abp/Http/RemoteServiceErrorInfo.cs
+++ b/framework/src/Volo.Abp.ExceptionHandling/Volo/Abp/Http/RemoteServiceErrorInfo.cs
@@ -12,27 +12,27 @@ public class RemoteServiceErrorInfo
///
/// Error code.
///
- public string Code { get; set; }
+ public string? Code { get; set; }
///
/// Error message.
///
- public string Message { get; set; }
+ public string? Message { get; set; }
///
/// Error details.
///
- public string Details { get; set; }
+ public string? Details { get; set; }
///
/// Error data.
///
- public IDictionary Data { get; set; }
+ public IDictionary? Data { get; set; }
///
/// Validation errors if exists.
///
- public RemoteServiceValidationErrorInfo[] ValidationErrors { get; set; }
+ public RemoteServiceValidationErrorInfo[]? ValidationErrors { get; set; }
///
/// Creates a new instance of .
@@ -49,7 +49,7 @@ public class RemoteServiceErrorInfo
/// Error details
/// Error message
/// Error data
- public RemoteServiceErrorInfo(string message, string details = null, string code = null, IDictionary data = null)
+ public RemoteServiceErrorInfo(string message, string? details = null, string? code = null, IDictionary? data = null)
{
Message = message;
Details = details;
diff --git a/framework/src/Volo.Abp.ExceptionHandling/Volo/Abp/Http/RemoteServiceValidationErrorInfo.cs b/framework/src/Volo.Abp.ExceptionHandling/Volo/Abp/Http/RemoteServiceValidationErrorInfo.cs
index 4b86bbf4e3..64a31d7041 100644
--- a/framework/src/Volo.Abp.ExceptionHandling/Volo/Abp/Http/RemoteServiceValidationErrorInfo.cs
+++ b/framework/src/Volo.Abp.ExceptionHandling/Volo/Abp/Http/RemoteServiceValidationErrorInfo.cs
@@ -11,12 +11,12 @@ public class RemoteServiceValidationErrorInfo
///
/// Validation error message.
///
- public string Message { get; set; }
+ public string Message { get; set; } = default!;
///
/// Relate invalid members (fields/properties).
///
- public string[] Members { get; set; }
+ public string[] Members { get; set; } = default!;
///
/// Creates a new instance of .
diff --git a/framework/src/Volo.Abp.Guids/Volo.Abp.Guids.csproj b/framework/src/Volo.Abp.Guids/Volo.Abp.Guids.csproj
index ed4e0af802..6aae43ce2a 100644
--- a/framework/src/Volo.Abp.Guids/Volo.Abp.Guids.csproj
+++ b/framework/src/Volo.Abp.Guids/Volo.Abp.Guids.csproj
@@ -5,6 +5,8 @@
netstandard2.0;netstandard2.1;net7.0
+ enable
+ Nullable
Volo.Abp.Guids
Volo.Abp.Guids
$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;
diff --git a/framework/src/Volo.Abp.Http.Client.Web/Volo/Abp/Http/Client/Web/AbpHttpClientWebModule.cs b/framework/src/Volo.Abp.Http.Client.Web/Volo/Abp/Http/Client/Web/AbpHttpClientWebModule.cs
index 5fcab7a7f1..655f96f068 100644
--- a/framework/src/Volo.Abp.Http.Client.Web/Volo/Abp/Http/Client/Web/AbpHttpClientWebModule.cs
+++ b/framework/src/Volo.Abp.Http.Client.Web/Volo/Abp/Http/Client/Web/AbpHttpClientWebModule.cs
@@ -31,7 +31,7 @@ public class AbpHttpClientWebModule : AbpModule
.ServiceProvider
.GetRequiredService()
.Modules
- .Select(m => m.Type.Assembly)
+ .SelectMany(m => m.AllAssemblies)
.Where(a => a.GetTypes().Any(AbpHttpClientProxyHelper.IsClientProxyService))
.Distinct())
{
diff --git a/framework/src/Volo.Abp.IdentityModel/Volo/Abp/IdentityModel/IdentityModelAuthenticationService.cs b/framework/src/Volo.Abp.IdentityModel/Volo/Abp/IdentityModel/IdentityModelAuthenticationService.cs
index 32952a7050..6f5f8eda95 100644
--- a/framework/src/Volo.Abp.IdentityModel/Volo/Abp/IdentityModel/IdentityModelAuthenticationService.cs
+++ b/framework/src/Volo.Abp.IdentityModel/Volo/Abp/IdentityModel/IdentityModelAuthenticationService.cs
@@ -245,8 +245,9 @@ public class IdentityModelAuthenticationService : IIdentityModelAuthenticationSe
throw new AbpException(response.ErrorDescription);
}
- Logger.LogInformation($"First copy your one-time code: {response.UserCode}");
- Logger.LogInformation($"Open {response.VerificationUri} in your browser...");
+ Logger.LogInformation($"Open your browser, go to: \"{response.VerificationUri}\"");
+ Logger.LogInformation($"and enter the following one-time code:");
+ Logger.LogInformation(response.UserCode);
for (var i = 0; i < ((response.ExpiresIn ?? 300) / response.Interval + 1); i++)
{
diff --git a/framework/src/Volo.Abp.Imaging.Abstractions/Volo/Abp/Imaging/ImageCompressor.cs b/framework/src/Volo.Abp.Imaging.Abstractions/Volo/Abp/Imaging/ImageCompressor.cs
index c68c7e3773..11789776c7 100644
--- a/framework/src/Volo.Abp.Imaging.Abstractions/Volo/Abp/Imaging/ImageCompressor.cs
+++ b/framework/src/Volo.Abp.Imaging.Abstractions/Volo/Abp/Imaging/ImageCompressor.cs
@@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.IO;
+using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using JetBrains.Annotations;
@@ -16,7 +17,7 @@ public class ImageCompressor : IImageCompressor, ITransientDependency
public ImageCompressor(IEnumerable imageCompressorContributors, ICancellationTokenProvider cancellationTokenProvider)
{
- ImageCompressorContributors = imageCompressorContributors;
+ ImageCompressorContributors = imageCompressorContributors.Reverse();
CancellationTokenProvider = cancellationTokenProvider;
}
diff --git a/framework/src/Volo.Abp.Imaging.Abstractions/Volo/Abp/Imaging/ImageResizer.cs b/framework/src/Volo.Abp.Imaging.Abstractions/Volo/Abp/Imaging/ImageResizer.cs
index 5576197797..139fc194dd 100644
--- a/framework/src/Volo.Abp.Imaging.Abstractions/Volo/Abp/Imaging/ImageResizer.cs
+++ b/framework/src/Volo.Abp.Imaging.Abstractions/Volo/Abp/Imaging/ImageResizer.cs
@@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.IO;
+using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using JetBrains.Annotations;
@@ -22,7 +23,7 @@ public class ImageResizer : IImageResizer, ITransientDependency
IOptions imageResizeOptions,
ICancellationTokenProvider cancellationTokenProvider)
{
- ImageResizerContributors = imageResizerContributors;
+ ImageResizerContributors = imageResizerContributors.Reverse();
CancellationTokenProvider = cancellationTokenProvider;
ImageResizeOptions = imageResizeOptions.Value;
}
diff --git a/framework/src/Volo.Abp.Json.Abstractions/Volo.Abp.Json.Abstractions.csproj b/framework/src/Volo.Abp.Json.Abstractions/Volo.Abp.Json.Abstractions.csproj
index d3f63e6e20..1be747846e 100644
--- a/framework/src/Volo.Abp.Json.Abstractions/Volo.Abp.Json.Abstractions.csproj
+++ b/framework/src/Volo.Abp.Json.Abstractions/Volo.Abp.Json.Abstractions.csproj
@@ -5,6 +5,8 @@
netstandard2.0;netstandard2.1;net7.0
+ enable
+ Nullable
Volo.Abp.Json.Abstractions
$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;
false
diff --git a/framework/src/Volo.Abp.Json.Abstractions/Volo/Abp/Json/AbpJsonOptions.cs b/framework/src/Volo.Abp.Json.Abstractions/Volo/Abp/Json/AbpJsonOptions.cs
index 043c1081d7..bed36c8afa 100644
--- a/framework/src/Volo.Abp.Json.Abstractions/Volo/Abp/Json/AbpJsonOptions.cs
+++ b/framework/src/Volo.Abp.Json.Abstractions/Volo/Abp/Json/AbpJsonOptions.cs
@@ -12,7 +12,7 @@ public class AbpJsonOptions
///
/// Format of output json date, Null or empty string means default format.
///
- public string OutputDateTimeFormat { get; set; }
+ public string? OutputDateTimeFormat { get; set; }
public AbpJsonOptions()
{
diff --git a/framework/src/Volo.Abp.Json.Newtonsoft/Volo.Abp.Json.Newtonsoft.csproj b/framework/src/Volo.Abp.Json.Newtonsoft/Volo.Abp.Json.Newtonsoft.csproj
index 5349254ea3..094a6e3c0a 100644
--- a/framework/src/Volo.Abp.Json.Newtonsoft/Volo.Abp.Json.Newtonsoft.csproj
+++ b/framework/src/Volo.Abp.Json.Newtonsoft/Volo.Abp.Json.Newtonsoft.csproj
@@ -5,6 +5,8 @@
netstandard2.0;netstandard2.1;net7.0
+ enable
+ Nullable
Volo.Abp.Json.Newtonsoft
Volo.Abp.Json.Newtonsoft
$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;
diff --git a/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpDateTimeConverter.cs b/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpDateTimeConverter.cs
index 408f38e772..effda40057 100644
--- a/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpDateTimeConverter.cs
+++ b/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpDateTimeConverter.cs
@@ -31,7 +31,7 @@ public class AbpDateTimeConverter : DateTimeConverterBase, ITransientDependency
return objectType == typeof(DateTime) || objectType == typeof(DateTime?);
}
- public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+ public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
{
var nullable = Nullable.GetUnderlyingType(objectType) != null;
if (reader.TokenType == JsonToken.Null)
@@ -46,7 +46,7 @@ public class AbpDateTimeConverter : DateTimeConverterBase, ITransientDependency
if (reader.TokenType == JsonToken.Date)
{
- return _clock.Normalize(reader.Value.To());
+ return _clock.Normalize(reader.Value!.To());
}
if (reader.TokenType != JsonToken.String)
@@ -72,11 +72,11 @@ public class AbpDateTimeConverter : DateTimeConverterBase, ITransientDependency
}
}
- var date = DateTime.Parse(dateText, _culture, _dateTimeStyles);
+ var date = DateTime.Parse(dateText!, _culture, _dateTimeStyles);
return _clock.Normalize(date);
}
- public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+ public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
{
if (value != null)
{
@@ -97,7 +97,7 @@ public class AbpDateTimeConverter : DateTimeConverterBase, ITransientDependency
}
else
{
- throw new JsonSerializationException($"Unexpected value when converting date. Expected DateTime or DateTimeOffset, got {value.GetType()}.");
+ throw new JsonSerializationException($"Unexpected value when converting date. Expected DateTime or DateTimeOffset, got {value?.GetType()}.");
}
}
diff --git a/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpNewtonsoftJsonSerializer.cs b/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpNewtonsoftJsonSerializer.cs
index ab65909cf9..2a21f5fbd7 100644
--- a/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpNewtonsoftJsonSerializer.cs
+++ b/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpNewtonsoftJsonSerializer.cs
@@ -26,12 +26,12 @@ public class AbpNewtonsoftJsonSerializer : IJsonSerializer, ITransientDependency
public T Deserialize(string jsonString, bool camelCase = true)
{
- return JsonConvert.DeserializeObject(jsonString, CreateJsonSerializerOptions(camelCase));
+ return JsonConvert.DeserializeObject(jsonString, CreateJsonSerializerOptions(camelCase))!;
}
public object Deserialize(Type type, string jsonString, bool camelCase = true)
{
- return JsonConvert.DeserializeObject(jsonString, type, CreateJsonSerializerOptions(camelCase));
+ return JsonConvert.DeserializeObject(jsonString, type, CreateJsonSerializerOptions(camelCase))!;
}
private readonly static ConcurrentDictionary JsonSerializerOptionsCache =
diff --git a/framework/src/Volo.Abp.Json.SystemTextJson/Volo.Abp.Json.SystemTextJson.csproj b/framework/src/Volo.Abp.Json.SystemTextJson/Volo.Abp.Json.SystemTextJson.csproj
index e157d5b7db..1fc81dd3ac 100644
--- a/framework/src/Volo.Abp.Json.SystemTextJson/Volo.Abp.Json.SystemTextJson.csproj
+++ b/framework/src/Volo.Abp.Json.SystemTextJson/Volo.Abp.Json.SystemTextJson.csproj
@@ -5,6 +5,8 @@
netstandard2.0;netstandard2.1;net7.0
+ enable
+ Nullable
Volo.Abp.Json.SystemTextJson
Volo.Abp.Json.SystemTextJson
$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;
diff --git a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializer.cs b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializer.cs
index 8313f6ee99..6f433ce918 100644
--- a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializer.cs
+++ b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializer.cs
@@ -22,12 +22,12 @@ public class AbpSystemTextJsonSerializer : IJsonSerializer, ITransientDependency
public T Deserialize(string jsonString, bool camelCase = true)
{
- return JsonSerializer.Deserialize(jsonString, CreateJsonSerializerOptions(camelCase));
+ return JsonSerializer.Deserialize(jsonString, CreateJsonSerializerOptions(camelCase))!;
}
public object Deserialize(Type type, string jsonString, bool camelCase = true)
{
- return JsonSerializer.Deserialize(jsonString, type, CreateJsonSerializerOptions(camelCase));
+ return JsonSerializer.Deserialize(jsonString, type, CreateJsonSerializerOptions(camelCase))!;
}
private static readonly ConcurrentDictionary JsonSerializerOptionsCache =
diff --git a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpNullableStringToGuidConverter.cs b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpNullableStringToGuidConverter.cs
index c80e5aa9a5..973faca170 100644
--- a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpNullableStringToGuidConverter.cs
+++ b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpNullableStringToGuidConverter.cs
@@ -6,7 +6,7 @@ namespace Volo.Abp.Json.SystemTextJson.JsonConverters;
public class AbpNullableStringToGuidConverter : JsonConverter
{
- private JsonSerializerOptions _writeJsonSerializerOptions;
+ private JsonSerializerOptions? _writeJsonSerializerOptions;
public override Guid? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
diff --git a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpStringToBooleanConverter.cs b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpStringToBooleanConverter.cs
index e704f2ceb0..443150e41a 100644
--- a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpStringToBooleanConverter.cs
+++ b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpStringToBooleanConverter.cs
@@ -8,7 +8,7 @@ namespace Volo.Abp.Json.SystemTextJson.JsonConverters;
public class AbpStringToBooleanConverter : JsonConverter
{
- private JsonSerializerOptions _writeJsonSerializerOptions;
+ private JsonSerializerOptions? _writeJsonSerializerOptions;
public override bool Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
diff --git a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpStringToEnumConverter.cs b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpStringToEnumConverter.cs
index 6b7f32807e..d1e8fc555d 100644
--- a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpStringToEnumConverter.cs
+++ b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpStringToEnumConverter.cs
@@ -9,9 +9,9 @@ public class AbpStringToEnumConverter : JsonConverter
{
private readonly JsonStringEnumConverter _innerJsonStringEnumConverter;
- private JsonSerializerOptions _readJsonSerializerOptions;
+ private JsonSerializerOptions? _readJsonSerializerOptions;
- private JsonSerializerOptions _writeJsonSerializerOptions;
+ private JsonSerializerOptions? _writeJsonSerializerOptions;
public AbpStringToEnumConverter()
: this(namingPolicy: null, allowIntegerValues: true)
@@ -19,7 +19,7 @@ public class AbpStringToEnumConverter : JsonConverter
}
- public AbpStringToEnumConverter(JsonNamingPolicy namingPolicy = null, bool allowIntegerValues = true)
+ public AbpStringToEnumConverter(JsonNamingPolicy? namingPolicy = null, bool allowIntegerValues = true)
{
_innerJsonStringEnumConverter = new JsonStringEnumConverter(namingPolicy, allowIntegerValues);
}
@@ -50,11 +50,11 @@ public class AbpStringToEnumConverter : JsonConverter
public override T ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
- return (T)Enum.Parse(typeToConvert, reader.GetString());
+ return (T)Enum.Parse(typeToConvert, reader.GetString()!);
}
public override void WriteAsPropertyName(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
{
- writer.WritePropertyName(Enum.GetName(typeof(T), value));
+ writer.WritePropertyName(Enum.GetName(typeof(T), value)!);
}
}
diff --git a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpStringToEnumFactory.cs b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpStringToEnumFactory.cs
index d94d85e546..bda510e5dc 100644
--- a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpStringToEnumFactory.cs
+++ b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpStringToEnumFactory.cs
@@ -7,7 +7,7 @@ namespace Volo.Abp.Json.SystemTextJson.JsonConverters;
public class AbpStringToEnumFactory : JsonConverterFactory
{
- private readonly JsonNamingPolicy _namingPolicy;
+ private readonly JsonNamingPolicy? _namingPolicy;
private readonly bool _allowIntegerValues;
public AbpStringToEnumFactory()
@@ -16,7 +16,7 @@ public class AbpStringToEnumFactory : JsonConverterFactory
}
- public AbpStringToEnumFactory(JsonNamingPolicy namingPolicy, bool allowIntegerValues)
+ public AbpStringToEnumFactory(JsonNamingPolicy? namingPolicy, bool allowIntegerValues)
{
_namingPolicy = namingPolicy;
_allowIntegerValues = allowIntegerValues;
@@ -33,7 +33,7 @@ public class AbpStringToEnumFactory : JsonConverterFactory
typeof(AbpStringToEnumConverter<>).MakeGenericType(typeToConvert),
BindingFlags.Instance | BindingFlags.Public,
binder: null,
- new object[] { _namingPolicy, _allowIntegerValues },
+ new object?[] { _namingPolicy, _allowIntegerValues },
culture: null)!;
}
}
diff --git a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpStringToGuidConverter.cs b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpStringToGuidConverter.cs
index 586e4462cf..5cb1062c0c 100644
--- a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpStringToGuidConverter.cs
+++ b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpStringToGuidConverter.cs
@@ -6,7 +6,7 @@ namespace Volo.Abp.Json.SystemTextJson.JsonConverters;
public class AbpStringToGuidConverter : JsonConverter
{
- private JsonSerializerOptions _writeJsonSerializerOptions;
+ private JsonSerializerOptions? _writeJsonSerializerOptions;
public override Guid Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
diff --git a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/JsonConverters/ObjectToInferredTypesConverter.cs b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/JsonConverters/ObjectToInferredTypesConverter.cs
index b1bffc95b8..bf017d041e 100644
--- a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/JsonConverters/ObjectToInferredTypesConverter.cs
+++ b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/JsonConverters/ObjectToInferredTypesConverter.cs
@@ -12,16 +12,16 @@ public class ObjectToInferredTypesConverter : JsonConverter
public override object Read(
ref Utf8JsonReader reader,
Type typeToConvert,
- JsonSerializerOptions options) => reader.TokenType switch
- {
- JsonTokenType.True => true,
- JsonTokenType.False => false,
- JsonTokenType.Number when reader.TryGetInt64(out long l) => l,
- JsonTokenType.Number => reader.GetDouble(),
- JsonTokenType.String when reader.TryGetDateTime(out DateTime datetime) => datetime,
- JsonTokenType.String => reader.GetString(),
- _ => JsonDocument.ParseValue(ref reader).RootElement.Clone()
- };
+ JsonSerializerOptions options) => (reader.TokenType switch
+ {
+ JsonTokenType.True => true,
+ JsonTokenType.False => false,
+ JsonTokenType.Number when reader.TryGetInt64(out long l) => l,
+ JsonTokenType.Number => reader.GetDouble(),
+ JsonTokenType.String when reader.TryGetDateTime(out DateTime datetime) => datetime,
+ JsonTokenType.String => reader.GetString(),
+ _ => JsonDocument.ParseValue(ref reader).RootElement.Clone()
+ })!;
public override void Write(
Utf8JsonWriter writer,
diff --git a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/Modifiers/AbpDateTimeConverterModifier.cs b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/Modifiers/AbpDateTimeConverterModifier.cs
index a691423cf3..ba19ccfa29 100644
--- a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/Modifiers/AbpDateTimeConverterModifier.cs
+++ b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/Modifiers/AbpDateTimeConverterModifier.cs
@@ -10,7 +10,7 @@ namespace Volo.Abp.Json.SystemTextJson.Modifiers;
public class AbpDateTimeConverterModifier
{
- private IServiceProvider _serviceProvider;
+ private IServiceProvider _serviceProvider = default!;
public Action CreateModifyAction(IServiceProvider serviceProvider)
{
diff --git a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/Modifiers/AbpIgnorePropertiesModifiers.cs b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/Modifiers/AbpIgnorePropertiesModifiers.cs
index 27a50395bf..7c1db739d1 100644
--- a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/Modifiers/AbpIgnorePropertiesModifiers.cs
+++ b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/Modifiers/AbpIgnorePropertiesModifiers.cs
@@ -9,7 +9,7 @@ namespace Volo.Abp.Json.SystemTextJson.Modifiers;
public class AbpIgnorePropertiesModifiers
where TClass : class
{
- private Expression> _propertySelector;
+ private Expression> _propertySelector = default!;
public Action CreateModifyAction(Expression> propertySelector)
{
diff --git a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/Modifiers/AbpIncludeExtraPropertiesModifiers.cs b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/Modifiers/AbpIncludeExtraPropertiesModifiers.cs
index f4a97e0e9d..c7fadc47db 100644
--- a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/Modifiers/AbpIncludeExtraPropertiesModifiers.cs
+++ b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/Modifiers/AbpIncludeExtraPropertiesModifiers.cs
@@ -17,7 +17,7 @@ public static class AbpIncludeExtraPropertiesModifiers
.Where(x => x.AttributeProvider is MemberInfo)
.FirstOrDefault(x =>
x.PropertyType == typeof(ExtraPropertyDictionary) &&
- x.AttributeProvider.As().Name == nameof(ExtensibleObject.ExtraProperties) &&
+ x.AttributeProvider!.As().Name == nameof(ExtensibleObject.ExtraProperties) &&
x.Set == null);
if (propertyJsonInfo != null)
diff --git a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/Modifiers/AbpIncludeNonPublicPropertiesModifiers.cs b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/Modifiers/AbpIncludeNonPublicPropertiesModifiers.cs
index 4669ddc666..cc13db8d0c 100644
--- a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/Modifiers/AbpIncludeNonPublicPropertiesModifiers.cs
+++ b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/Modifiers/AbpIncludeNonPublicPropertiesModifiers.cs
@@ -9,7 +9,7 @@ namespace Volo.Abp.Json.SystemTextJson.Modifiers;
public class AbpIncludeNonPublicPropertiesModifiers
where TClass : class
{
- private Expression> _propertySelector;
+ private Expression> _propertySelector = default!;
public Action CreateModifyAction(Expression> propertySelector)
{
diff --git a/framework/src/Volo.Abp.Ldap.Abstractions/Volo.Abp.Ldap.Abstractions.csproj b/framework/src/Volo.Abp.Ldap.Abstractions/Volo.Abp.Ldap.Abstractions.csproj
index 9a61150096..6e25ebe8e6 100644
--- a/framework/src/Volo.Abp.Ldap.Abstractions/Volo.Abp.Ldap.Abstractions.csproj
+++ b/framework/src/Volo.Abp.Ldap.Abstractions/Volo.Abp.Ldap.Abstractions.csproj
@@ -5,6 +5,8 @@
netstandard2.0;netstandard2.1;net7.0
+ enable
+ Nullable
Volo.Abp.Ldap.Abstractions
Volo.Abp.Ldap.Abstractions
$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;
diff --git a/framework/src/Volo.Abp.Ldap.Abstractions/Volo/Abp/Ldap/ILdapSettingProvider.cs b/framework/src/Volo.Abp.Ldap.Abstractions/Volo/Abp/Ldap/ILdapSettingProvider.cs
index efc109a762..c7320a36fa 100644
--- a/framework/src/Volo.Abp.Ldap.Abstractions/Volo/Abp/Ldap/ILdapSettingProvider.cs
+++ b/framework/src/Volo.Abp.Ldap.Abstractions/Volo/Abp/Ldap/ILdapSettingProvider.cs
@@ -4,15 +4,15 @@ namespace Volo.Abp.Ldap;
public interface ILdapSettingProvider
{
- public Task GetServerHostAsync();
+ public Task GetServerHostAsync();
public Task GetServerPortAsync();
- public Task GetBaseDcAsync();
+ public Task GetBaseDcAsync();
- public Task GetDomainAsync();
+ public Task GetDomainAsync();
- public Task GetUserNameAsync();
+ public Task GetUserNameAsync();
- public Task GetPasswordAsync();
+ public Task GetPasswordAsync();
}
diff --git a/framework/src/Volo.Abp.Ldap/Volo.Abp.Ldap.csproj b/framework/src/Volo.Abp.Ldap/Volo.Abp.Ldap.csproj
index 951cbf3be2..aee7d78518 100644
--- a/framework/src/Volo.Abp.Ldap/Volo.Abp.Ldap.csproj
+++ b/framework/src/Volo.Abp.Ldap/Volo.Abp.Ldap.csproj
@@ -5,6 +5,8 @@
netstandard2.0;netstandard2.1;net7.0
+ enable
+ Nullable
Volo.Abp.Ldap
Volo.Abp.Ldap
$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;
diff --git a/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/LdapSettingProvider.cs b/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/LdapSettingProvider.cs
index ab36c1bf5f..cf43f11d43 100644
--- a/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/LdapSettingProvider.cs
+++ b/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/LdapSettingProvider.cs
@@ -14,7 +14,7 @@ public class LdapSettingProvider : ILdapSettingProvider, ITransientDependency
SettingProvider = settingProvider;
}
- public async Task GetServerHostAsync()
+ public async Task GetServerHostAsync()
{
return await SettingProvider.GetOrNullAsync(LdapSettingNames.ServerHost);
}
@@ -24,22 +24,22 @@ public class LdapSettingProvider : ILdapSettingProvider, ITransientDependency
return (await SettingProvider.GetOrNullAsync(LdapSettingNames.ServerPort))?.To() ?? default;
}
- public async Task GetBaseDcAsync()
+ public async Task GetBaseDcAsync()
{
return await SettingProvider.GetOrNullAsync(LdapSettingNames.BaseDc);
}
- public async Task GetDomainAsync()
+ public async Task GetDomainAsync()
{
return await SettingProvider.GetOrNullAsync(LdapSettingNames.Domain);
}
- public async Task GetUserNameAsync()
+ public async Task GetUserNameAsync()
{
return await SettingProvider.GetOrNullAsync(LdapSettingNames.UserName);
}
- public async Task GetPasswordAsync()
+ public async Task GetPasswordAsync()
{
return await SettingProvider.GetOrNullAsync(LdapSettingNames.Password);
}
diff --git a/framework/src/Volo.Abp.Localization.Abstractions/Microsoft/Extensions/Localization/AbpStringLocalizerFactoryExtensions.cs b/framework/src/Volo.Abp.Localization.Abstractions/Microsoft/Extensions/Localization/AbpStringLocalizerFactoryExtensions.cs
index 8aa2515a54..492372cc30 100644
--- a/framework/src/Volo.Abp.Localization.Abstractions/Microsoft/Extensions/Localization/AbpStringLocalizerFactoryExtensions.cs
+++ b/framework/src/Volo.Abp.Localization.Abstractions/Microsoft/Extensions/Localization/AbpStringLocalizerFactoryExtensions.cs
@@ -6,15 +6,13 @@ namespace Microsoft.Extensions.Localization;
public static class AbpStringLocalizerFactoryExtensions
{
- [CanBeNull]
- public static IStringLocalizer CreateDefaultOrNull(this IStringLocalizerFactory localizerFactory)
+ public static IStringLocalizer? CreateDefaultOrNull(this IStringLocalizerFactory localizerFactory)
{
return (localizerFactory as IAbpStringLocalizerFactory)
?.CreateDefaultOrNull();
}
- [CanBeNull]
- public static IStringLocalizer CreateByResourceNameOrNull(
+ public static IStringLocalizer? CreateByResourceNameOrNull(
this IStringLocalizerFactory localizerFactory,
string resourceName)
{
@@ -36,8 +34,7 @@ public static class AbpStringLocalizerFactoryExtensions
return localizer;
}
- [ItemCanBeNull]
- public static async Task CreateByResourceNameOrNullAsync(
+ public static async Task CreateByResourceNameOrNullAsync(
this IStringLocalizerFactory localizerFactory,
string resourceName)
{
diff --git a/framework/src/Volo.Abp.Localization.Abstractions/Microsoft/Extensions/Localization/IAbpStringLocalizerFactory.cs b/framework/src/Volo.Abp.Localization.Abstractions/Microsoft/Extensions/Localization/IAbpStringLocalizerFactory.cs
index 8f6699a13d..030617583a 100644
--- a/framework/src/Volo.Abp.Localization.Abstractions/Microsoft/Extensions/Localization/IAbpStringLocalizerFactory.cs
+++ b/framework/src/Volo.Abp.Localization.Abstractions/Microsoft/Extensions/Localization/IAbpStringLocalizerFactory.cs
@@ -5,12 +5,9 @@ namespace Microsoft.Extensions.Localization;
public interface IAbpStringLocalizerFactory
{
- [CanBeNull]
- IStringLocalizer CreateDefaultOrNull();
+ IStringLocalizer? CreateDefaultOrNull();
- [CanBeNull]
- IStringLocalizer CreateByResourceNameOrNull([NotNull] string resourceName);
+ IStringLocalizer? CreateByResourceNameOrNull([NotNull] string resourceName);
- [ItemCanBeNull]
- Task CreateByResourceNameOrNullAsync([NotNull] string resourceName);
+ Task CreateByResourceNameOrNullAsync([NotNull] string resourceName);
}
diff --git a/framework/src/Volo.Abp.Localization.Abstractions/Volo.Abp.Localization.Abstractions.csproj b/framework/src/Volo.Abp.Localization.Abstractions/Volo.Abp.Localization.Abstractions.csproj
index 952d59b739..1fb66c9b7c 100644
--- a/framework/src/Volo.Abp.Localization.Abstractions/Volo.Abp.Localization.Abstractions.csproj
+++ b/framework/src/Volo.Abp.Localization.Abstractions/Volo.Abp.Localization.Abstractions.csproj
@@ -5,6 +5,8 @@
netstandard2.0;netstandard2.1;net7.0
+ enable
+ Nullable
Volo.Abp.Localization.Abstractions
Volo.Abp.Localization.Abstractions
$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;
diff --git a/framework/src/Volo.Abp.Localization.Abstractions/Volo/Abp/Localization/HasNameWithLocalizableDisplayNameExtensions.cs b/framework/src/Volo.Abp.Localization.Abstractions/Volo/Abp/Localization/HasNameWithLocalizableDisplayNameExtensions.cs
index a73e4a6509..348d5b696b 100644
--- a/framework/src/Volo.Abp.Localization.Abstractions/Volo/Abp/Localization/HasNameWithLocalizableDisplayNameExtensions.cs
+++ b/framework/src/Volo.Abp.Localization.Abstractions/Volo/Abp/Localization/HasNameWithLocalizableDisplayNameExtensions.cs
@@ -10,7 +10,7 @@ public static class HasNameWithLocalizableDisplayNameExtensions
public static string GetLocalizedDisplayName(
[NotNull] this IHasNameWithLocalizableDisplayName source,
[NotNull] IStringLocalizerFactory stringLocalizerFactory,
- [CanBeNull] string localizationNamePrefix = "DisplayName:")
+ string? localizationNamePrefix = "DisplayName:")
{
if (source.DisplayName != null)
{
diff --git a/framework/src/Volo.Abp.Localization.Abstractions/Volo/Abp/Localization/IHasNameWithLocalizableDisplayName.cs b/framework/src/Volo.Abp.Localization.Abstractions/Volo/Abp/Localization/IHasNameWithLocalizableDisplayName.cs
index f582a31379..de29047ddf 100644
--- a/framework/src/Volo.Abp.Localization.Abstractions/Volo/Abp/Localization/IHasNameWithLocalizableDisplayName.cs
+++ b/framework/src/Volo.Abp.Localization.Abstractions/Volo/Abp/Localization/IHasNameWithLocalizableDisplayName.cs
@@ -7,6 +7,5 @@ public interface IHasNameWithLocalizableDisplayName
[NotNull]
public string Name { get; }
- [CanBeNull]
- public ILocalizableString DisplayName { get; }
+ public ILocalizableString? DisplayName { get; }
}
diff --git a/framework/src/Volo.Abp.Localization.Abstractions/Volo/Abp/Localization/LocalizableString.cs b/framework/src/Volo.Abp.Localization.Abstractions/Volo/Abp/Localization/LocalizableString.cs
index a98f207a55..038d170f2a 100644
--- a/framework/src/Volo.Abp.Localization.Abstractions/Volo/Abp/Localization/LocalizableString.cs
+++ b/framework/src/Volo.Abp.Localization.Abstractions/Volo/Abp/Localization/LocalizableString.cs
@@ -7,16 +7,14 @@ namespace Volo.Abp.Localization;
public class LocalizableString : ILocalizableString, IAsyncLocalizableString
{
- [CanBeNull]
- public string ResourceName { get; }
+ public string? ResourceName { get; }
- [CanBeNull]
- public Type ResourceType { get; }
+ public Type? ResourceType { get; }
[NotNull]
public string Name { get; }
- public LocalizableString([CanBeNull] Type resourceType, [NotNull] string name)
+ public LocalizableString(Type? resourceType, [NotNull] string name)
{
Name = Check.NotNullOrEmpty(name, nameof(name));
ResourceType = resourceType;
@@ -27,7 +25,7 @@ public class LocalizableString : ILocalizableString, IAsyncLocalizableString
}
}
- public LocalizableString([NotNull] string name, [CanBeNull] string resourceName = null)
+ public LocalizableString([NotNull] string name, string? resourceName = null)
{
Name = Check.NotNullOrEmpty(name, nameof(name));
ResourceName = resourceName;
@@ -79,7 +77,7 @@ public class LocalizableString : ILocalizableString, IAsyncLocalizableString
return result;
}
- private IStringLocalizer CreateStringLocalizerOrNull(IStringLocalizerFactory stringLocalizerFactory)
+ private IStringLocalizer? CreateStringLocalizerOrNull(IStringLocalizerFactory stringLocalizerFactory)
{
if (ResourceType != null)
{
@@ -98,7 +96,7 @@ public class LocalizableString : ILocalizableString, IAsyncLocalizableString
return stringLocalizerFactory.CreateDefaultOrNull();
}
- private async Task CreateStringLocalizerOrNullAsync(IStringLocalizerFactory stringLocalizerFactory)
+ private async Task CreateStringLocalizerOrNullAsync(IStringLocalizerFactory stringLocalizerFactory)
{
if (ResourceType != null)
{
@@ -127,7 +125,7 @@ public class LocalizableString : ILocalizableString, IAsyncLocalizableString
return new LocalizableString(resourceType, name);
}
- public static LocalizableString Create([NotNull] string name, [CanBeNull] string resourceName = null)
+ public static LocalizableString Create([NotNull] string name, string? resourceName = null)
{
return new LocalizableString(name, resourceName);
}
diff --git a/framework/src/Volo.Abp.Localization.Abstractions/Volo/Abp/Localization/LocalizationResourceNameAttribute.cs b/framework/src/Volo.Abp.Localization.Abstractions/Volo/Abp/Localization/LocalizationResourceNameAttribute.cs
index 303214393b..6657ba5d2e 100644
--- a/framework/src/Volo.Abp.Localization.Abstractions/Volo/Abp/Localization/LocalizationResourceNameAttribute.cs
+++ b/framework/src/Volo.Abp.Localization.Abstractions/Volo/Abp/Localization/LocalizationResourceNameAttribute.cs
@@ -12,7 +12,7 @@ public class LocalizationResourceNameAttribute : Attribute
Name = name;
}
- public static LocalizationResourceNameAttribute GetOrNull(Type resourceType)
+ public static LocalizationResourceNameAttribute? GetOrNull(Type resourceType)
{
return resourceType
.GetCustomAttributes(true)
@@ -22,6 +22,6 @@ public class LocalizationResourceNameAttribute : Attribute
public static string GetName(Type resourceType)
{
- return GetOrNull(resourceType)?.Name ?? resourceType.FullName;
+ return (GetOrNull(resourceType)?.Name ?? resourceType.FullName)!;
}
}
diff --git a/framework/src/Volo.Abp.Localization/Volo.Abp.Localization.csproj b/framework/src/Volo.Abp.Localization/Volo.Abp.Localization.csproj
index 8b889e2057..f4c5c4ece2 100644
--- a/framework/src/Volo.Abp.Localization/Volo.Abp.Localization.csproj
+++ b/framework/src/Volo.Abp.Localization/Volo.Abp.Localization.csproj
@@ -5,6 +5,8 @@
netstandard2.0;netstandard2.1;net7.0
+ enable
+ Nullable
Volo.Abp.Localization
Volo.Abp.Localization
$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;
diff --git a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/AbpDictionaryBasedStringLocalizer.cs b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/AbpDictionaryBasedStringLocalizer.cs
index cf5c1ebb82..86133cdf17 100644
--- a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/AbpDictionaryBasedStringLocalizer.cs
+++ b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/AbpDictionaryBasedStringLocalizer.cs
@@ -118,7 +118,7 @@ public class AbpDictionaryBasedStringLocalizer : IAbpStringLocalizer
return value;
}
- protected virtual LocalizedString GetLocalizedStringOrNull(
+ protected virtual LocalizedString? GetLocalizedStringOrNull(
string name,
string cultureName,
bool tryDefaults = true)
@@ -153,7 +153,7 @@ public class AbpDictionaryBasedStringLocalizer : IAbpStringLocalizer
//Try to get from default language
if (!Resource.DefaultCultureName.IsNullOrEmpty())
{
- var strDefault = Resource.Contributors.GetOrNull(Resource.DefaultCultureName, name);
+ var strDefault = Resource.Contributors.GetOrNull(Resource.DefaultCultureName!, name);
if (strDefault != null)
{
return strDefault;
@@ -208,7 +208,7 @@ public class AbpDictionaryBasedStringLocalizer : IAbpStringLocalizer
//Fill all strings from default culture
if (!Resource.DefaultCultureName.IsNullOrEmpty())
{
- Resource.Contributors.Fill(Resource.DefaultCultureName, allStrings, includeDynamicContributors);
+ Resource.Contributors.Fill(Resource.DefaultCultureName!, allStrings, includeDynamicContributors);
}
//Overwrite all strings from the language based on country culture
@@ -268,7 +268,7 @@ public class AbpDictionaryBasedStringLocalizer : IAbpStringLocalizer
if (!Resource.DefaultCultureName.IsNullOrEmpty())
{
await Resource.Contributors.FillAsync(
- Resource.DefaultCultureName,
+ Resource.DefaultCultureName!,
allStrings,
includeDynamicContributors
);
diff --git a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/AbpEnumLocalizer.cs b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/AbpEnumLocalizer.cs
index 3fc053da6a..b2acb3d072 100644
--- a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/AbpEnumLocalizer.cs
+++ b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/AbpEnumLocalizer.cs
@@ -19,14 +19,14 @@ public class AbpEnumLocalizer : IAbpEnumLocalizer, ITransientDependency
return GetStringInternal(enumType, enumValue, StringLocalizerFactory.CreateDefaultOrNull());
}
- public virtual string GetString(Type enumType, object enumValue, params IStringLocalizer[] specifyLocalizers)
+ public virtual string GetString(Type enumType, object enumValue, params IStringLocalizer?[] specifyLocalizers)
{
return GetStringInternal(enumType, enumValue, specifyLocalizers);
}
- protected virtual string GetStringInternal(Type enumType, object enumValue, params IStringLocalizer[] specifyLocalizers)
+ protected virtual string GetStringInternal(Type enumType, object enumValue, params IStringLocalizer?[] specifyLocalizers)
{
- var memberName = enumType.GetEnumName(enumValue);
+ var memberName = enumType.GetEnumName(enumValue)!;
var localizedString = GetStringOrNull(
specifyLocalizers,
new[]
@@ -42,7 +42,7 @@ public class AbpEnumLocalizer : IAbpEnumLocalizer, ITransientDependency
return localizedString ?? memberName;
}
- protected virtual string GetStringOrNull(IStringLocalizer[] localizers, IEnumerable keys)
+ protected virtual string? GetStringOrNull(IStringLocalizer?[] localizers, IEnumerable keys)
{
foreach (var key in keys)
{
diff --git a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/AbpLocalizationOptions.cs b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/AbpLocalizationOptions.cs
index 5228f886e9..0fd9d47ac8 100644
--- a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/AbpLocalizationOptions.cs
+++ b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/AbpLocalizationOptions.cs
@@ -11,7 +11,7 @@ public class AbpLocalizationOptions
///
/// Used as the default resource when resource was not specified on a localization operation.
///
- public Type DefaultResourceType { get; set; }
+ public Type? DefaultResourceType { get; set; }
public ITypeList GlobalContributors { get; }
diff --git a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/AbpStringLocalizerExtensions.cs b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/AbpStringLocalizerExtensions.cs
index 9b3bb2c201..91c7126a97 100644
--- a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/AbpStringLocalizerExtensions.cs
+++ b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/AbpStringLocalizerExtensions.cs
@@ -35,7 +35,7 @@ public static class AbpStringLocalizerExtensions
throw new AbpException($"Could not find the _localizer field inside the {typeof(StringLocalizer<>).FullName} class. Probably its name has changed. Please report this issue to the ABP framework.");
}
- return localizerField.GetValue(stringLocalizer) as IStringLocalizer;
+ return (localizerField.GetValue(stringLocalizer) as IStringLocalizer)!;
}
public static IEnumerable GetAllStrings(
diff --git a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/AbpStringLocalizerFactory.cs b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/AbpStringLocalizerFactory.cs
index b89a54abd9..f40385c128 100644
--- a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/AbpStringLocalizerFactory.cs
+++ b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/AbpStringLocalizerFactory.cs
@@ -52,12 +52,12 @@ public class AbpStringLocalizerFactory : IStringLocalizerFactory, IAbpStringLoca
return CreateInternal(resource.ResourceName, resource, lockCache);
}
- public IStringLocalizer CreateByResourceNameOrNull(string resourceName)
+ public IStringLocalizer? CreateByResourceNameOrNull(string resourceName)
{
return CreateByResourceNameOrNullInternal(resourceName, lockCache: true);
}
- private IStringLocalizer CreateByResourceNameOrNullInternal(
+ private IStringLocalizer? CreateByResourceNameOrNullInternal(
string resourceName,
bool lockCache)
{
@@ -74,12 +74,12 @@ public class AbpStringLocalizerFactory : IStringLocalizerFactory, IAbpStringLoca
return CreateInternal(resourceName, resource, lockCache);
}
- public Task CreateByResourceNameOrNullAsync(string resourceName)
+ public Task CreateByResourceNameOrNullAsync(string resourceName)
{
return CreateByResourceNameOrNullInternalAsync(resourceName, lockCache: true);
}
- private async Task CreateByResourceNameOrNullInternalAsync(
+ private async Task CreateByResourceNameOrNullInternalAsync(
string resourceName,
bool lockCache)
{
@@ -175,7 +175,7 @@ public class AbpStringLocalizerFactory : IStringLocalizerFactory, IAbpStringLoca
{
resource.Contributors.Add(
Activator
- .CreateInstance(globalContributorType)
+ .CreateInstance(globalContributorType)!
.As()
);
}
@@ -194,7 +194,7 @@ public class AbpStringLocalizerFactory : IStringLocalizerFactory, IAbpStringLoca
.BaseResourceNames
.Select(x => CreateByResourceNameOrNullInternal(x, lockCache: false))
.Where(x => x != null)
- .ToList(),
+ .ToList()!,
AbpLocalizationOptions
)
);
@@ -206,7 +206,7 @@ public class AbpStringLocalizerFactory : IStringLocalizerFactory, IAbpStringLoca
{
resource.Contributors.Add(
Activator
- .CreateInstance(globalContributorType)
+ .CreateInstance(globalContributorType)!
.As()
);
}
@@ -259,7 +259,7 @@ public class AbpStringLocalizerFactory : IStringLocalizerFactory, IAbpStringLoca
}
}
- public IStringLocalizer CreateDefaultOrNull()
+ public IStringLocalizer? CreateDefaultOrNull()
{
if (AbpLocalizationOptions.DefaultResourceType == null)
{
diff --git a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/External/IExternalLocalizationStore.cs b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/External/IExternalLocalizationStore.cs
index cd48bb1bd9..c2aa55cd2f 100644
--- a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/External/IExternalLocalizationStore.cs
+++ b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/External/IExternalLocalizationStore.cs
@@ -5,11 +5,9 @@ namespace Volo.Abp.Localization.External;
public interface IExternalLocalizationStore
{
- [CanBeNull]
- LocalizationResourceBase GetResourceOrNull([NotNull] string resourceName);
+ LocalizationResourceBase? GetResourceOrNull([NotNull] string resourceName);
- [ItemCanBeNull]
- Task GetResourceOrNullAsync([NotNull] string resourceName);
+ Task GetResourceOrNullAsync([NotNull] string resourceName);
Task GetResourceNamesAsync();
diff --git a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/External/NullExternalLocalizationStore.cs b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/External/NullExternalLocalizationStore.cs
index 508f947981..891beba134 100644
--- a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/External/NullExternalLocalizationStore.cs
+++ b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/External/NullExternalLocalizationStore.cs
@@ -6,14 +6,14 @@ namespace Volo.Abp.Localization.External;
public class NullExternalLocalizationStore : IExternalLocalizationStore, ISingletonDependency
{
- public LocalizationResourceBase GetResourceOrNull(string resourceName)
+ public LocalizationResourceBase? GetResourceOrNull(string resourceName)
{
return null;
}
- public Task GetResourceOrNullAsync(string resourceName)
+ public Task GetResourceOrNullAsync(string resourceName)
{
- return Task.FromResult(null);
+ return Task.FromResult(null);
}
public Task GetResourceNamesAsync()
diff --git a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/ILanguageInfo.cs b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/ILanguageInfo.cs
index d4e06e9af5..e8ae6935de 100644
--- a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/ILanguageInfo.cs
+++ b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/ILanguageInfo.cs
@@ -8,5 +8,5 @@ public interface ILanguageInfo
string DisplayName { get; }
- string FlagIcon { get; }
+ string? FlagIcon { get; }
}
diff --git a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/ILocalizableStringSerializer.cs b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/ILocalizableStringSerializer.cs
index 6f7a487b6c..7d068b9494 100644
--- a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/ILocalizableStringSerializer.cs
+++ b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/ILocalizableStringSerializer.cs
@@ -2,7 +2,7 @@
public interface ILocalizableStringSerializer
{
- string Serialize(ILocalizableString localizableString);
+ string? Serialize(ILocalizableString localizableString);
ILocalizableString Deserialize(string value);
}
\ No newline at end of file
diff --git a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/ILocalizationDictionary.cs b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/ILocalizationDictionary.cs
index d5fcab206b..e6879c0007 100644
--- a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/ILocalizationDictionary.cs
+++ b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/ILocalizationDictionary.cs
@@ -10,7 +10,7 @@ public interface ILocalizationDictionary
{
string CultureName { get; }
- LocalizedString GetOrNull(string name);
+ LocalizedString? GetOrNull(string name);
void Fill(Dictionary dictionary);
}
diff --git a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/ILocalizationResourceContributor.cs b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/ILocalizationResourceContributor.cs
index 2a79d20821..2d3ade519f 100644
--- a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/ILocalizationResourceContributor.cs
+++ b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/ILocalizationResourceContributor.cs
@@ -10,7 +10,7 @@ public interface ILocalizationResourceContributor
void Initialize(LocalizationResourceInitializationContext context);
- LocalizedString GetOrNull(string cultureName, string name);
+ LocalizedString? GetOrNull(string cultureName, string name);
void Fill(string cultureName, Dictionary dictionary);
diff --git a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/Json/JsonLocalizationDictionaryBuilder.cs b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/Json/JsonLocalizationDictionaryBuilder.cs
index 04ec79aaf6..e4b66148a5 100644
--- a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/Json/JsonLocalizationDictionaryBuilder.cs
+++ b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/Json/JsonLocalizationDictionaryBuilder.cs
@@ -2,7 +2,6 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Text.Json;
-using JetBrains.Annotations;
using Microsoft.Extensions.Localization;
namespace Volo.Abp.Localization.Json;
@@ -13,8 +12,7 @@ public static class JsonLocalizationDictionaryBuilder
/// Builds an from given file.
///
/// Path of the file
- [CanBeNull]
- public static ILocalizationDictionary BuildFromFile(string filePath)
+ public static ILocalizationDictionary? BuildFromFile(string filePath)
{
try
{
@@ -38,10 +36,9 @@ public static class JsonLocalizationDictionaryBuilder
/// Builds an from given json string.
///
/// Json string
- [CanBeNull]
- public static ILocalizationDictionary BuildFromJsonString(string jsonString)
+ public static ILocalizationDictionary? BuildFromJsonString(string jsonString)
{
- JsonLocalizationFile jsonFile;
+ JsonLocalizationFile? jsonFile;
try
{
jsonFile = JsonSerializer.Deserialize(jsonString, DeserializeOptions);
@@ -50,6 +47,11 @@ public static class JsonLocalizationDictionaryBuilder
{
throw new AbpException("Can not parse json string. " + ex.Message);
}
+
+ if (jsonFile == null)
+ {
+ return null;
+ }
var cultureCode = jsonFile.Culture;
if (string.IsNullOrEmpty(cultureCode))
diff --git a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/Json/JsonLocalizationFile.cs b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/Json/JsonLocalizationFile.cs
index 08daf70682..8470e2696f 100644
--- a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/Json/JsonLocalizationFile.cs
+++ b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/Json/JsonLocalizationFile.cs
@@ -7,7 +7,7 @@ public class JsonLocalizationFile
///
/// Culture name; eg : en , en-us, zh-CN
///
- public string Culture { get; set; }
+ public string Culture { get; set; } = default!;
public Dictionary Texts { get; set; }
diff --git a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LanguageInfo.cs b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LanguageInfo.cs
index 9183b89c4e..a2274b5a69 100644
--- a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LanguageInfo.cs
+++ b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LanguageInfo.cs
@@ -8,19 +8,18 @@ namespace Volo.Abp.Localization;
public class LanguageInfo : ILanguageInfo
{
[NotNull]
- public virtual string CultureName { get; protected set; }
+ public virtual string CultureName { get; protected set; } = default!;
[NotNull]
- public virtual string UiCultureName { get; protected set; }
+ public virtual string UiCultureName { get; protected set; } = default!;
[NotNull]
- public virtual string DisplayName { get; protected set; }
+ public virtual string DisplayName { get; protected set; } = default!;
[NotNull]
- public virtual string TwoLetterISOLanguageName { get; protected set; }
+ public virtual string TwoLetterISOLanguageName { get; protected set; } = default!;
- [CanBeNull]
- public virtual string FlagIcon { get; set; }
+ public virtual string? FlagIcon { get; set; }
protected LanguageInfo()
@@ -30,30 +29,30 @@ public class LanguageInfo : ILanguageInfo
public LanguageInfo(
string cultureName,
- string uiCultureName = null,
- string displayName = null,
- string flagIcon = null)
+ string? uiCultureName = null,
+ string? displayName = null,
+ string? flagIcon = null)
{
ChangeCultureInternal(cultureName, uiCultureName, displayName);
FlagIcon = flagIcon;
}
- public virtual void ChangeCulture(string cultureName, string uiCultureName = null, string displayName = null)
+ public virtual void ChangeCulture(string cultureName, string? uiCultureName = null, string? displayName = null)
{
ChangeCultureInternal(cultureName, uiCultureName, displayName);
}
- private void ChangeCultureInternal(string cultureName, string uiCultureName, string displayName)
+ private void ChangeCultureInternal(string cultureName, string? uiCultureName, string? displayName)
{
CultureName = Check.NotNullOrWhiteSpace(cultureName, nameof(cultureName));
- UiCultureName = !uiCultureName.IsNullOrWhiteSpace()
+ UiCultureName = (!uiCultureName.IsNullOrWhiteSpace()
? uiCultureName
- : cultureName;
+ : cultureName)!;
- DisplayName = !displayName.IsNullOrWhiteSpace()
+ DisplayName = (!displayName.IsNullOrWhiteSpace()
? displayName
- : cultureName;
+ : cultureName)!;
TwoLetterISOLanguageName = new CultureInfo(cultureName)
.TwoLetterISOLanguageName;
diff --git a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LanguageInfoExtensions.cs b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LanguageInfoExtensions.cs
index 8909708b67..7b60cce40d 100644
--- a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LanguageInfoExtensions.cs
+++ b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LanguageInfoExtensions.cs
@@ -6,10 +6,10 @@ namespace Volo.Abp.Localization;
public static class LanguageInfoExtensions
{
- public static T FindByCulture(
+ public static T? FindByCulture(
[NotNull] this IEnumerable languages,
[NotNull] string cultureName,
- [CanBeNull] string uiCultureName = null)
+ string? uiCultureName = null)
where T : class, ILanguageInfo
{
if (uiCultureName == null)
diff --git a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LocalizableStringSerializer.cs b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LocalizableStringSerializer.cs
index 5006d62ea8..02b9cc8fac 100644
--- a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LocalizableStringSerializer.cs
+++ b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LocalizableStringSerializer.cs
@@ -13,7 +13,7 @@ public class LocalizableStringSerializer : ILocalizableStringSerializer, ITransi
LocalizationOptions = localizationOptions.Value;
}
- public virtual string Serialize(ILocalizableString localizableString)
+ public virtual string? Serialize(ILocalizableString? localizableString)
{
if (localizableString == null)
{
diff --git a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LocalizationResource.cs b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LocalizationResource.cs
index 7a55f1f8a3..b6e0da82e4 100644
--- a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LocalizationResource.cs
+++ b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LocalizationResource.cs
@@ -12,8 +12,8 @@ public class LocalizationResource : LocalizationResourceBase
public LocalizationResource(
[NotNull] Type resourceType,
- [CanBeNull] string defaultCultureName = null,
- [CanBeNull] ILocalizationResourceContributor initialContributor = null)
+ string? defaultCultureName = null,
+ ILocalizationResourceContributor? initialContributor = null)
: base(
LocalizationResourceNameAttribute.GetName(resourceType),
defaultCultureName,
diff --git a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LocalizationResourceBase.cs b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LocalizationResourceBase.cs
index a7ec4fb93b..6cbbd98188 100644
--- a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LocalizationResourceBase.cs
+++ b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LocalizationResourceBase.cs
@@ -10,16 +10,15 @@ public abstract class LocalizationResourceBase
public List BaseResourceNames { get; }
- [CanBeNull]
- public string DefaultCultureName { get; set; }
+ public string? DefaultCultureName { get; set; }
[NotNull]
public LocalizationResourceContributorList Contributors { get; }
public LocalizationResourceBase(
[NotNull] string resourceName,
- [CanBeNull] string defaultCultureName = null,
- [CanBeNull] ILocalizationResourceContributor initialContributor = null)
+ string? defaultCultureName = null,
+ ILocalizationResourceContributor? initialContributor = null)
{
ResourceName = Check.NotNullOrWhiteSpace(resourceName, nameof(resourceName));
DefaultCultureName = defaultCultureName;
diff --git a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LocalizationResourceContributorList.cs b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LocalizationResourceContributorList.cs
index 6df15920da..9f11aa4051 100644
--- a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LocalizationResourceContributorList.cs
+++ b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LocalizationResourceContributorList.cs
@@ -7,7 +7,7 @@ namespace Volo.Abp.Localization;
public class LocalizationResourceContributorList : List
{
- public LocalizedString GetOrNull(
+ public LocalizedString? GetOrNull(
string cultureName,
string name,
bool includeDynamicContributors = true)
diff --git a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LocalizationResourceDictionary.cs b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LocalizationResourceDictionary.cs
index 4a88eac199..f6487a85b7 100644
--- a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LocalizationResourceDictionary.cs
+++ b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LocalizationResourceDictionary.cs
@@ -8,12 +8,12 @@ public class LocalizationResourceDictionary : Dictionary _resourcesByTypes = new();
- public LocalizationResource Add([CanBeNull] string defaultCultureName = null)
+ public LocalizationResource Add(string? defaultCultureName = null)
{
return Add(typeof(TResouce), defaultCultureName);
}
- public LocalizationResource Add(Type resourceType, [CanBeNull] string defaultCultureName = null)
+ public LocalizationResource Add(Type resourceType, string? defaultCultureName = null)
{
var resourceName = LocalizationResourceNameAttribute.GetName(resourceType);
if (ContainsKey(resourceName))
@@ -29,7 +29,7 @@ public class LocalizationResourceDictionary : Dictionary
- public virtual LocalizedString GetOrNull(string name)
+ public virtual LocalizedString? GetOrNull(string name)
{
return Dictionary.GetOrDefault(name);
}
diff --git a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/VirtualFiles/Json/JsonVirtualFileLocalizationResourceContributor.cs b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/VirtualFiles/Json/JsonVirtualFileLocalizationResourceContributor.cs
index fcafed49f3..71ca2744a0 100644
--- a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/VirtualFiles/Json/JsonVirtualFileLocalizationResourceContributor.cs
+++ b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/VirtualFiles/Json/JsonVirtualFileLocalizationResourceContributor.cs
@@ -19,7 +19,7 @@ public class JsonVirtualFileLocalizationResourceContributor : VirtualFileLocaliz
return file.Name.EndsWith(".json", StringComparison.OrdinalIgnoreCase);
}
- protected override ILocalizationDictionary CreateDictionaryFromFileContent(string jsonString)
+ protected override ILocalizationDictionary? CreateDictionaryFromFileContent(string jsonString)
{
return JsonLocalizationDictionaryBuilder.BuildFromJsonString(jsonString);
}
diff --git a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/VirtualFiles/VirtualFileLocalizationResourceContributorBase.cs b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/VirtualFiles/VirtualFileLocalizationResourceContributorBase.cs
index 40bb9de7c5..d87169ea31 100644
--- a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/VirtualFiles/VirtualFileLocalizationResourceContributorBase.cs
+++ b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/VirtualFiles/VirtualFileLocalizationResourceContributorBase.cs
@@ -16,11 +16,11 @@ public abstract class VirtualFileLocalizationResourceContributorBase : ILocaliza
public bool IsDynamic => false;
private readonly string _virtualPath;
- private IVirtualFileProvider _virtualFileProvider;
- private Dictionary _dictionaries;
+ private IVirtualFileProvider _virtualFileProvider = default!;
+ private Dictionary? _dictionaries;
private bool _subscribedForChanges;
private readonly object _syncObj = new object();
- private LocalizationResourceBase _resource;
+ private LocalizationResourceBase _resource = default!;
protected VirtualFileLocalizationResourceContributorBase(string virtualPath)
{
@@ -33,7 +33,7 @@ public abstract class VirtualFileLocalizationResourceContributorBase : ILocaliza
_virtualFileProvider = context.ServiceProvider.GetRequiredService();
}
- public virtual LocalizedString GetOrNull(string cultureName, string name)
+ public virtual LocalizedString? GetOrNull(string cultureName, string name)
{
return GetDictionaries().GetOrDefault(cultureName)?.GetOrNull(name);
}
@@ -118,8 +118,7 @@ public abstract class VirtualFileLocalizationResourceContributorBase : ILocaliza
protected abstract bool CanParseFile(IFileInfo file);
- [CanBeNull]
- protected virtual ILocalizationDictionary CreateDictionaryFromFile(IFileInfo file)
+ protected virtual ILocalizationDictionary? CreateDictionaryFromFile(IFileInfo file)
{
using (var stream = file.CreateReadStream())
{
@@ -127,6 +126,5 @@ public abstract class VirtualFileLocalizationResourceContributorBase : ILocaliza
}
}
- [CanBeNull]
- protected abstract ILocalizationDictionary CreateDictionaryFromFileContent(string fileContent);
+ protected abstract ILocalizationDictionary? CreateDictionaryFromFileContent(string fileContent);
}
diff --git a/framework/src/Volo.Abp.Minify/Volo.Abp.Minify.csproj b/framework/src/Volo.Abp.Minify/Volo.Abp.Minify.csproj
index f552541094..9ec0a51e40 100644
--- a/framework/src/Volo.Abp.Minify/Volo.Abp.Minify.csproj
+++ b/framework/src/Volo.Abp.Minify/Volo.Abp.Minify.csproj
@@ -5,6 +5,8 @@
netstandard2.0;netstandard2.1;net7.0
+ enable
+ Nullable
Volo.Abp.Minify
Volo.Abp.Minify
$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;
diff --git a/framework/src/Volo.Abp.Minify/Volo/Abp/Minify/IMinifier.cs b/framework/src/Volo.Abp.Minify/Volo/Abp/Minify/IMinifier.cs
index 4f816a2f48..4c4f1881da 100644
--- a/framework/src/Volo.Abp.Minify/Volo/Abp/Minify/IMinifier.cs
+++ b/framework/src/Volo.Abp.Minify/Volo/Abp/Minify/IMinifier.cs
@@ -6,6 +6,6 @@ public interface IMinifier
{
string Minify(
string source,
- [CanBeNull] string fileName = null,
- [CanBeNull] string originalFileName = null);
+ string? fileName = null,
+ string? originalFileName = null);
}
diff --git a/framework/src/Volo.Abp.Minify/Volo/Abp/Minify/NUglify/NUglifyCssMinifier.cs b/framework/src/Volo.Abp.Minify/Volo/Abp/Minify/NUglify/NUglifyCssMinifier.cs
index 281f5c6aa3..d2f78d95d6 100644
--- a/framework/src/Volo.Abp.Minify/Volo/Abp/Minify/NUglify/NUglifyCssMinifier.cs
+++ b/framework/src/Volo.Abp.Minify/Volo/Abp/Minify/NUglify/NUglifyCssMinifier.cs
@@ -5,7 +5,7 @@ namespace Volo.Abp.Minify.NUglify;
public class NUglifyCssMinifier : NUglifyMinifierBase, ICssMinifier
{
- protected override UglifyResult UglifySource(string source, string fileName)
+ protected override UglifyResult UglifySource(string source, string? fileName)
{
return Uglify.Css(source, fileName);
}
diff --git a/framework/src/Volo.Abp.Minify/Volo/Abp/Minify/NUglify/NUglifyException.cs b/framework/src/Volo.Abp.Minify/Volo/Abp/Minify/NUglify/NUglifyException.cs
index 6b4d68b07e..bf623771d3 100644
--- a/framework/src/Volo.Abp.Minify/Volo/Abp/Minify/NUglify/NUglifyException.cs
+++ b/framework/src/Volo.Abp.Minify/Volo/Abp/Minify/NUglify/NUglifyException.cs
@@ -7,7 +7,7 @@ namespace Volo.Abp.Minify.NUglify;
public class NUglifyException : AbpException
{
- public List Errors { get; set; }
+ public List? Errors { get; set; }
public NUglifyException(string message, List errors)
: base(message)
diff --git a/framework/src/Volo.Abp.Minify/Volo/Abp/Minify/NUglify/NUglifyHtmlMinifier.cs b/framework/src/Volo.Abp.Minify/Volo/Abp/Minify/NUglify/NUglifyHtmlMinifier.cs
index dc8bbe22ea..6698b3cdd0 100644
--- a/framework/src/Volo.Abp.Minify/Volo/Abp/Minify/NUglify/NUglifyHtmlMinifier.cs
+++ b/framework/src/Volo.Abp.Minify/Volo/Abp/Minify/NUglify/NUglifyHtmlMinifier.cs
@@ -5,7 +5,7 @@ namespace Volo.Abp.Minify.NUglify;
public class NUglifyHtmlMinifier : NUglifyMinifierBase, IHtmlMinifier
{
- protected override UglifyResult UglifySource(string source, string fileName)
+ protected override UglifyResult UglifySource(string source, string? fileName)
{
return Uglify.Html(source, sourceFileName: fileName);
}
diff --git a/framework/src/Volo.Abp.Minify/Volo/Abp/Minify/NUglify/NUglifyJavascriptMinifier.cs b/framework/src/Volo.Abp.Minify/Volo/Abp/Minify/NUglify/NUglifyJavascriptMinifier.cs
index 5b8fa54ce3..6c13d00129 100644
--- a/framework/src/Volo.Abp.Minify/Volo/Abp/Minify/NUglify/NUglifyJavascriptMinifier.cs
+++ b/framework/src/Volo.Abp.Minify/Volo/Abp/Minify/NUglify/NUglifyJavascriptMinifier.cs
@@ -5,7 +5,7 @@ namespace Volo.Abp.Minify.NUglify;
public class NUglifyJavascriptMinifier : NUglifyMinifierBase, IJavascriptMinifier
{
- protected override UglifyResult UglifySource(string source, string fileName)
+ protected override UglifyResult UglifySource(string source, string? fileName)
{
return Uglify.Js(source, fileName);
}
diff --git a/framework/src/Volo.Abp.Minify/Volo/Abp/Minify/NUglify/NUglifyMinifierBase.cs b/framework/src/Volo.Abp.Minify/Volo/Abp/Minify/NUglify/NUglifyMinifierBase.cs
index d5018a1b28..28e0267e17 100644
--- a/framework/src/Volo.Abp.Minify/Volo/Abp/Minify/NUglify/NUglifyMinifierBase.cs
+++ b/framework/src/Volo.Abp.Minify/Volo/Abp/Minify/NUglify/NUglifyMinifierBase.cs
@@ -8,7 +8,7 @@ namespace Volo.Abp.Minify.NUglify;
public abstract class NUglifyMinifierBase : IMinifier, ITransientDependency
{
- private static void CheckErrors(UglifyResult result, string originalFileName)
+ private static void CheckErrors(UglifyResult result, string? originalFileName)
{
if (result.HasErrors)
{
@@ -28,8 +28,8 @@ public abstract class NUglifyMinifierBase : IMinifier, ITransientDependency
public string Minify(
string source,
- string fileName = null,
- string originalFileName = null)
+ string? fileName = null,
+ string? originalFileName = null)
{
try
{
@@ -50,5 +50,5 @@ public abstract class NUglifyMinifierBase : IMinifier, ITransientDependency
}
}
- protected abstract UglifyResult UglifySource(string source, string fileName);
+ protected abstract UglifyResult UglifySource(string source, string? fileName);
}
diff --git a/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/DistributedEvents/IncomingEventRecord.cs b/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/DistributedEvents/IncomingEventRecord.cs
index 22c1d860d1..e6ddc87bd6 100644
--- a/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/DistributedEvents/IncomingEventRecord.cs
+++ b/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/DistributedEvents/IncomingEventRecord.cs
@@ -48,13 +48,20 @@ public class IncomingEventRecord :
public IncomingEventInfo ToIncomingEventInfo()
{
- return new IncomingEventInfo(
+ var info = new IncomingEventInfo(
Id,
MessageId,
EventName,
EventData,
CreationTime
);
+
+ foreach (var property in ExtraProperties)
+ {
+ info.SetProperty(property.Key, property.Value);
+ }
+
+ return info;
}
public void MarkAsProcessed(DateTime processedTime)
diff --git a/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/DistributedEvents/OutgoingEventRecord.cs b/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/DistributedEvents/OutgoingEventRecord.cs
index 15dfac38f6..0f0798532b 100644
--- a/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/DistributedEvents/OutgoingEventRecord.cs
+++ b/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/DistributedEvents/OutgoingEventRecord.cs
@@ -41,11 +41,18 @@ public class OutgoingEventRecord :
public OutgoingEventInfo ToOutgoingEventInfo()
{
- return new OutgoingEventInfo(
+ var info = new OutgoingEventInfo(
Id,
EventName,
EventData,
CreationTime
);
+
+ foreach (var property in ExtraProperties)
+ {
+ info.SetProperty(property.Key, property.Value);
+ }
+
+ return info;
}
}
diff --git a/framework/src/Volo.Abp.MultiLingualObjects/Volo.Abp.MultiLingualObjects.csproj b/framework/src/Volo.Abp.MultiLingualObjects/Volo.Abp.MultiLingualObjects.csproj
index 54c8469153..5b45ea638f 100644
--- a/framework/src/Volo.Abp.MultiLingualObjects/Volo.Abp.MultiLingualObjects.csproj
+++ b/framework/src/Volo.Abp.MultiLingualObjects/Volo.Abp.MultiLingualObjects.csproj
@@ -5,6 +5,8 @@
netstandard2.0;netstandard2.1;net7.0
+ enable
+ Nullable
Volo.Abp.MultiLingualObject
$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;
false
diff --git a/framework/src/Volo.Abp.MultiLingualObjects/Volo/Abp/MultiLingualObjects/MultiLingualObjectManager.cs b/framework/src/Volo.Abp.MultiLingualObjects/Volo/Abp/MultiLingualObjects/MultiLingualObjectManager.cs
index 908431e997..c41605ad0e 100644
--- a/framework/src/Volo.Abp.MultiLingualObjects/Volo/Abp/MultiLingualObjects/MultiLingualObjectManager.cs
+++ b/framework/src/Volo.Abp.MultiLingualObjects/Volo/Abp/MultiLingualObjects/MultiLingualObjectManager.cs
@@ -1,97 +1,97 @@
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.Linq;
-using System.Threading.Tasks;
-using Volo.Abp.DependencyInjection;
-using Volo.Abp.Localization;
-using Volo.Abp.Settings;
-
-namespace Volo.Abp.MultiLingualObjects;
-
-public class MultiLingualObjectManager : IMultiLingualObjectManager, ITransientDependency
-{
- protected ISettingProvider SettingProvider { get; }
-
- protected const int MaxCultureFallbackDepth = 5;
-
- public MultiLingualObjectManager(ISettingProvider settingProvider)
- {
- SettingProvider = settingProvider;
- }
- public virtual async Task GetTranslationAsync(
- IEnumerable translations,
- string? culture,
- bool fallbackToParentCultures)
- where TTranslation : class, IObjectTranslation
-
- {
- culture ??= CultureInfo.CurrentUICulture.Name;
-
- if (translations == null || !translations.Any())
- {
- return null;
- }
-
- var translation = translations.FirstOrDefault(pt => pt.Language == culture);
- if (translation != null)
- {
- return translation;
- }
-
- if (fallbackToParentCultures)
- {
- translation = GetTranslationBasedOnCulturalRecursive(
- CultureInfo.CurrentUICulture.Parent,
- translations,
- 0
- );
-
- if (translation != null)
- {
- return translation;
- }
- }
-
- var defaultLanguage = await SettingProvider.GetOrNullAsync(LocalizationSettingNames.DefaultLanguage);
-
- translation = translations.FirstOrDefault(pt => pt.Language == defaultLanguage);
- if (translation != null)
- {
- return translation;
- }
-
- translation = translations.FirstOrDefault();
- return translation;
- }
-
- public virtual Task GetTranslationAsync(
- TMultiLingual multiLingual,
- string? culture = null,
- bool fallbackToParentCultures = true)
- where TMultiLingual : IMultiLingualObject
- where TTranslation : class, IObjectTranslation
- {
- return GetTranslationAsync(multiLingual.Translations, culture: culture, fallbackToParentCultures: fallbackToParentCultures);
- }
-
- protected virtual TTranslation? GetTranslationBasedOnCulturalRecursive(
- CultureInfo culture, IEnumerable translations, int currentDepth)
- where TTranslation : class, IObjectTranslation
- {
- if (culture == null ||
- culture.Name.IsNullOrWhiteSpace() ||
- translations == null || !translations.Any() ||
- currentDepth > MaxCultureFallbackDepth)
- {
- return null;
- }
-
- var translation = translations.FirstOrDefault(pt => pt.Language.Equals(culture.Name, StringComparison.OrdinalIgnoreCase));
- return translation ?? GetTranslationBasedOnCulturalRecursive(culture.Parent, translations, currentDepth + 1);
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Threading.Tasks;
+using Volo.Abp.DependencyInjection;
+using Volo.Abp.Localization;
+using Volo.Abp.Settings;
+
+namespace Volo.Abp.MultiLingualObjects;
+
+public class MultiLingualObjectManager : IMultiLingualObjectManager, ITransientDependency
+{
+ protected ISettingProvider SettingProvider { get; }
+
+ protected const int MaxCultureFallbackDepth = 5;
+
+ public MultiLingualObjectManager(ISettingProvider settingProvider)
+ {
+ SettingProvider = settingProvider;
+ }
+ public virtual async Task GetTranslationAsync(
+ IEnumerable? translations,
+ string? culture,
+ bool fallbackToParentCultures)
+ where TTranslation : class, IObjectTranslation
+
+ {
+ culture ??= CultureInfo.CurrentUICulture.Name;
+
+ if (translations == null || !translations.Any())
+ {
+ return null;
+ }
+
+ var translation = translations.FirstOrDefault(pt => pt.Language == culture);
+ if (translation != null)
+ {
+ return translation;
+ }
+
+ if (fallbackToParentCultures)
+ {
+ translation = GetTranslationBasedOnCulturalRecursive(
+ CultureInfo.CurrentUICulture.Parent,
+ translations,
+ 0
+ );
+
+ if (translation != null)
+ {
+ return translation;
+ }
+ }
+
+ var defaultLanguage = await SettingProvider.GetOrNullAsync(LocalizationSettingNames.DefaultLanguage);
+
+ translation = translations.FirstOrDefault(pt => pt.Language == defaultLanguage);
+ if (translation != null)
+ {
+ return translation;
+ }
+
+ translation = translations.FirstOrDefault();
+ return translation;
+ }
+
+ public virtual Task GetTranslationAsync(
+ TMultiLingual multiLingual,
+ string? culture = null,
+ bool fallbackToParentCultures = true)
+ where TMultiLingual : IMultiLingualObject
+ where TTranslation : class, IObjectTranslation
+ {
+ return GetTranslationAsync(multiLingual.Translations, culture: culture, fallbackToParentCultures: fallbackToParentCultures);
+ }
+
+ protected virtual TTranslation? GetTranslationBasedOnCulturalRecursive(
+ CultureInfo? culture, IEnumerable? translations, int currentDepth)
+ where TTranslation : class, IObjectTranslation
+ {
+ if (culture == null ||
+ culture.Name.IsNullOrWhiteSpace() ||
+ translations == null || !translations.Any() ||
+ currentDepth > MaxCultureFallbackDepth)
+ {
+ return null;
+ }
+
+ var translation = translations.FirstOrDefault(pt => pt.Language.Equals(culture.Name, StringComparison.OrdinalIgnoreCase));
+ return translation ?? GetTranslationBasedOnCulturalRecursive(culture.Parent, translations, currentDepth + 1);
}
- public virtual async Task> GetBulkTranslationsAsync(IEnumerable> translationsCombined, string? culture, bool fallbackToParentCultures)
+ public virtual async Task> GetBulkTranslationsAsync(IEnumerable>? translationsCombined, string? culture, bool fallbackToParentCultures)
where TTranslation : class, IObjectTranslation
{
culture ??= CultureInfo.CurrentUICulture.Name;
@@ -180,7 +180,7 @@ public class MultiLingualObjectManager : IMultiLingualObjectManager, ITransientD
}
public virtual async Task> GetBulkTranslationsAsync(IEnumerable multiLinguals, string? culture, bool fallbackToParentCultures)
- where TMultiLingual : IMultiLingualObject
+ where TMultiLingual : IMultiLingualObject
where TTranslation : class, IObjectTranslation
{
var resInitial = await GetBulkTranslationsAsync(multiLinguals.Select(x => x.Translations), culture, fallbackToParentCultures);
@@ -193,4 +193,4 @@ public class MultiLingualObjectManager : IMultiLingualObjectManager, ITransientD
}
return res;
}
-}
+}
diff --git a/framework/src/Volo.Abp.ObjectExtending/Volo.Abp.ObjectExtending.csproj b/framework/src/Volo.Abp.ObjectExtending/Volo.Abp.ObjectExtending.csproj
index de9711ff6a..e427f154c7 100644
--- a/framework/src/Volo.Abp.ObjectExtending/Volo.Abp.ObjectExtending.csproj
+++ b/framework/src/Volo.Abp.ObjectExtending/Volo.Abp.ObjectExtending.csproj
@@ -5,6 +5,8 @@
netstandard2.0;netstandard2.1;net7.0
+ enable
+ Nullable
Volo.Abp.ObjectExtending
Volo.Abp.ObjectExtending
$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;
diff --git a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/Data/ExtraPropertyDictionaryExtensions.cs b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/Data/ExtraPropertyDictionaryExtensions.cs
index d5de504afc..6c4cd02d1b 100644
--- a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/Data/ExtraPropertyDictionaryExtensions.cs
+++ b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/Data/ExtraPropertyDictionaryExtensions.cs
@@ -13,7 +13,7 @@ public static class ExtraPropertyDictionaryExtensions
return (T)extraPropertyDictionary[key];
}
- extraPropertyDictionary[key] = Enum.Parse(typeof(T), extraPropertyDictionary[key].ToString(), ignoreCase: true);
+ extraPropertyDictionary[key] = Enum.Parse(typeof(T), extraPropertyDictionary[key].ToString()!, ignoreCase: true);
return (T)extraPropertyDictionary[key];
}
@@ -24,7 +24,7 @@ public static class ExtraPropertyDictionaryExtensions
return extraPropertyDictionary[key];
}
- extraPropertyDictionary[key] = Enum.Parse(enumType, extraPropertyDictionary[key].ToString(), ignoreCase: true);
+ extraPropertyDictionary[key] = Enum.Parse(enumType, extraPropertyDictionary[key].ToString()!, ignoreCase: true);
return extraPropertyDictionary[key];
}
diff --git a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/Data/HasExtraPropertiesExtensions.cs b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/Data/HasExtraPropertiesExtensions.cs
index 2e32a1b7dc..7423052772 100644
--- a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/Data/HasExtraPropertiesExtensions.cs
+++ b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/Data/HasExtraPropertiesExtensions.cs
@@ -18,13 +18,13 @@ public static class HasExtraPropertiesExtensions
return source.ExtraProperties.ContainsKey(name);
}
- public static object GetProperty(this IHasExtraProperties source, string name, object defaultValue = null)
+ public static object? GetProperty(this IHasExtraProperties source, string name, object? defaultValue = null)
{
return source.ExtraProperties?.GetOrDefault(name)
?? defaultValue;
}
- public static TProperty GetProperty(this IHasExtraProperties source, string name, TProperty defaultValue = default)
+ public static TProperty? GetProperty(this IHasExtraProperties source, string name, TProperty? defaultValue = default)
{
var value = source.GetProperty(name);
if (value == null)
@@ -42,7 +42,7 @@ public static class HasExtraPropertiesExtensions
if (conversionType == typeof(Guid))
{
- return (TProperty)TypeDescriptor.GetConverter(conversionType).ConvertFromInvariantString(value.ToString());
+ return (TProperty)TypeDescriptor.GetConverter(conversionType).ConvertFromInvariantString(value.ToString()!)!;
}
if (conversionType.IsEnum)
@@ -80,7 +80,7 @@ public static class HasExtraPropertiesExtensions
return source;
}
- public static TSource SetDefaultsForExtraProperties(this TSource source, Type objectType = null)
+ public static TSource SetDefaultsForExtraProperties(this TSource source, Type? objectType = null)
where TSource : IHasExtraProperties
{
if (objectType == null)
@@ -98,7 +98,7 @@ public static class HasExtraPropertiesExtensions
continue;
}
- source.ExtraProperties[property.Name] = property.GetDefaultValue();
+ source.ExtraProperties[property.Name] = property.GetDefaultValue()!;
}
return source;
diff --git a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ExtensibleObjectMapper.cs b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ExtensibleObjectMapper.cs
index 2de527866b..fbf277c55b 100644
--- a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ExtensibleObjectMapper.cs
+++ b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ExtensibleObjectMapper.cs
@@ -27,7 +27,7 @@ public static class ExtensibleObjectMapper
[NotNull] TSource source,
[NotNull] TDestination destination,
MappingPropertyDefinitionChecks? definitionChecks = null,
- string[] ignoredProperties = null)
+ string[]? ignoredProperties = null)
where TSource : IHasExtraProperties
where TDestination : IHasExtraProperties
{
@@ -78,7 +78,7 @@ public static class ExtensibleObjectMapper
[NotNull] Dictionary sourceDictionary,
[NotNull] Dictionary destinationDictionary,
MappingPropertyDefinitionChecks? definitionChecks = null,
- string[] ignoredProperties = null)
+ string[]? ignoredProperties = null)
where TSource : IHasExtraProperties
where TDestination : IHasExtraProperties
{
@@ -113,7 +113,7 @@ public static class ExtensibleObjectMapper
[NotNull] Dictionary sourceDictionary,
[NotNull] Dictionary destinationDictionary,
MappingPropertyDefinitionChecks? definitionChecks = null,
- string[] ignoredProperties = null)
+ string[]? ignoredProperties = null)
{
Check.AssignableTo(sourceType, nameof(sourceType));
Check.AssignableTo(destinationType, nameof(destinationType));
@@ -140,7 +140,7 @@ public static class ExtensibleObjectMapper
public static bool CanMapProperty(
[NotNull] string propertyName,
MappingPropertyDefinitionChecks? definitionChecks = null,
- string[] ignoredProperties = null)
+ string[]? ignoredProperties = null)
{
return CanMapProperty(
typeof(TSource),
@@ -156,7 +156,7 @@ public static class ExtensibleObjectMapper
[NotNull] Type destinationType,
[NotNull] string propertyName,
MappingPropertyDefinitionChecks? definitionChecks = null,
- string[] ignoredProperties = null)
+ string[]? ignoredProperties = null)
{
Check.AssignableTo(sourceType, nameof(sourceType));
Check.AssignableTo(destinationType, nameof(destinationType));
@@ -175,10 +175,10 @@ public static class ExtensibleObjectMapper
private static bool CanMapProperty(
[NotNull] string propertyName,
- [CanBeNull] ObjectExtensionInfo sourceObjectExtension,
- [CanBeNull] ObjectExtensionInfo destinationObjectExtension,
+ ObjectExtensionInfo? sourceObjectExtension,
+ ObjectExtensionInfo? destinationObjectExtension,
MappingPropertyDefinitionChecks? definitionChecks = null,
- string[] ignoredProperties = null)
+ string[]? ignoredProperties = null)
{
Check.NotNull(propertyName, nameof(propertyName));
diff --git a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ExtensibleObjectValidator.cs b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ExtensibleObjectValidator.cs
index 8252051fad..09228fe927 100644
--- a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ExtensibleObjectValidator.cs
+++ b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ExtensibleObjectValidator.cs
@@ -13,7 +13,7 @@ public static class ExtensibleObjectValidator
public static void CheckValue(
[NotNull] IHasExtraProperties extensibleObject,
[NotNull] string propertyName,
- [CanBeNull] object value)
+ object? value)
{
var validationErrors = GetValidationErrors(
extensibleObject,
@@ -29,7 +29,7 @@ public static class ExtensibleObjectValidator
public static bool IsValid(
[NotNull] IHasExtraProperties extensibleObject,
- [CanBeNull] ValidationContext objectValidationContext = null)
+ ValidationContext? objectValidationContext = null)
{
return GetValidationErrors(
extensibleObject,
@@ -40,8 +40,8 @@ public static class ExtensibleObjectValidator
public static bool IsValid(
[NotNull] IHasExtraProperties extensibleObject,
[NotNull] string propertyName,
- [CanBeNull] object value,
- [CanBeNull] ValidationContext objectValidationContext = null)
+ object? value,
+ ValidationContext? objectValidationContext = null)
{
return GetValidationErrors(
extensibleObject,
@@ -54,7 +54,7 @@ public static class ExtensibleObjectValidator
[NotNull]
public static List GetValidationErrors(
[NotNull] IHasExtraProperties extensibleObject,
- [CanBeNull] ValidationContext objectValidationContext = null)
+ ValidationContext? objectValidationContext = null)
{
var validationErrors = new List();
@@ -71,8 +71,8 @@ public static class ExtensibleObjectValidator
public static List GetValidationErrors(
[NotNull] IHasExtraProperties extensibleObject,
[NotNull] string propertyName,
- [CanBeNull] object value,
- [CanBeNull] ValidationContext objectValidationContext = null)
+ object? value,
+ ValidationContext? objectValidationContext = null)
{
var validationErrors = new List();
@@ -90,7 +90,7 @@ public static class ExtensibleObjectValidator
public static void AddValidationErrors(
[NotNull] IHasExtraProperties extensibleObject,
[NotNull] List validationErrors,
- [CanBeNull] ValidationContext objectValidationContext = null)
+ ValidationContext? objectValidationContext = null)
{
Check.NotNull(extensibleObject, nameof(extensibleObject));
Check.NotNull(validationErrors, nameof(validationErrors));
@@ -100,7 +100,7 @@ public static class ExtensibleObjectValidator
objectValidationContext = new ValidationContext(
extensibleObject,
null,
- new Dictionary()
+ new Dictionary()
);
}
@@ -133,8 +133,8 @@ public static class ExtensibleObjectValidator
[NotNull] IHasExtraProperties extensibleObject,
[NotNull] List validationErrors,
[NotNull] string propertyName,
- [CanBeNull] object value,
- [CanBeNull] ValidationContext objectValidationContext = null)
+ object? value,
+ ValidationContext? objectValidationContext = null)
{
Check.NotNull(extensibleObject, nameof(extensibleObject));
Check.NotNull(validationErrors, nameof(validationErrors));
@@ -145,7 +145,7 @@ public static class ExtensibleObjectValidator
objectValidationContext = new ValidationContext(
extensibleObject,
null,
- new Dictionary()
+ new Dictionary()
);
}
@@ -203,7 +203,7 @@ public static class ExtensibleObjectValidator
List validationErrors,
ValidationContext objectValidationContext,
ObjectExtensionPropertyInfo property,
- object value)
+ object? value)
{
AddPropertyValidationAttributeErrors(
extensibleObject,
@@ -227,7 +227,7 @@ public static class ExtensibleObjectValidator
List validationErrors,
ValidationContext objectValidationContext,
ObjectExtensionPropertyInfo property,
- object value)
+ object? value)
{
var validationAttributes = property.GetValidationAttributes();
@@ -261,7 +261,7 @@ public static class ExtensibleObjectValidator
List validationErrors,
ValidationContext objectValidationContext,
ObjectExtensionPropertyInfo property,
- object value)
+ object? value)
{
if (!property.Validators.Any())
{
diff --git a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ExtensionPropertyHelper.cs b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ExtensionPropertyHelper.cs
index d2b6976bf1..89a5e8c87c 100644
--- a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ExtensionPropertyHelper.cs
+++ b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ExtensionPropertyHelper.cs
@@ -20,10 +20,10 @@ internal static class ExtensionPropertyHelper
}
}
- public static object GetDefaultValue(
+ public static object? GetDefaultValue(
Type propertyType,
- Func defaultValueFactory,
- object defaultValue)
+ Func? defaultValueFactory,
+ object? defaultValue)
{
if (defaultValueFactory != null)
{
diff --git a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/HasExtraPropertiesObjectExtendingExtensions.cs b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/HasExtraPropertiesObjectExtendingExtensions.cs
index 12c6bfb984..d44a900314 100644
--- a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/HasExtraPropertiesObjectExtendingExtensions.cs
+++ b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/HasExtraPropertiesObjectExtendingExtensions.cs
@@ -24,7 +24,7 @@ public static class HasExtraPropertiesObjectExtendingExtensions
[NotNull] this TSource source,
[NotNull] TDestination destination,
MappingPropertyDefinitionChecks? definitionChecks = null,
- string[] ignoredProperties = null)
+ string[]? ignoredProperties = null)
where TSource : IHasExtraProperties
where TDestination : IHasExtraProperties
{
diff --git a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/IBasicObjectExtensionPropertyInfo.cs b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/IBasicObjectExtensionPropertyInfo.cs
index 8fd6270eda..86f34354a8 100644
--- a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/IBasicObjectExtensionPropertyInfo.cs
+++ b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/IBasicObjectExtensionPropertyInfo.cs
@@ -20,19 +20,16 @@ public interface IBasicObjectExtensionPropertyInfo
[NotNull]
public List> Validators { get; }
- [CanBeNull]
- public ILocalizableString DisplayName { get; }
+ public ILocalizableString? DisplayName { get; }
///
/// Uses as the default value if was not set.
///
- [CanBeNull]
- public object DefaultValue { get; set; }
+ public object? DefaultValue { get; set; }
///
/// Used with the first priority to create the default value for the property.
/// Uses to the if this was not set.
///
- [CanBeNull]
- public Func DefaultValueFactory { get; set; }
+ public Func? DefaultValueFactory { get; set; }
}
diff --git a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/Modularity/EntityExtensionConfiguration.cs b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/Modularity/EntityExtensionConfiguration.cs
index 82c6658c23..83429e36ce 100644
--- a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/Modularity/EntityExtensionConfiguration.cs
+++ b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/Modularity/EntityExtensionConfiguration.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
+using System.Linq;
using JetBrains.Annotations;
using Volo.Abp.Localization;
@@ -26,7 +27,7 @@ public class EntityExtensionConfiguration
[NotNull]
public virtual EntityExtensionConfiguration AddOrUpdateProperty(
[NotNull] string propertyName,
- [CanBeNull] Action configureAction = null)
+ Action? configureAction = null)
{
return AddOrUpdateProperty(
typeof(TProperty),
@@ -39,7 +40,7 @@ public class EntityExtensionConfiguration
public virtual EntityExtensionConfiguration AddOrUpdateProperty(
[NotNull] Type propertyType,
[NotNull] string propertyName,
- [CanBeNull] Action configureAction = null)
+ Action? configureAction = null)
{
Check.NotNull(propertyType, nameof(propertyType));
Check.NotNull(propertyName, nameof(propertyName));
@@ -74,7 +75,7 @@ public class EntityExtensionConfiguration
[NotNull]
public virtual ImmutableList GetProperties()
{
- return Properties.Values.ToImmutableList();
+ return Properties.Values.OrderBy(t => t.UI.Order).ToImmutableList();
}
private static void NormalizeProperty(ExtensionPropertyConfiguration propertyInfo)
diff --git a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/Modularity/ExtensionPropertyConfiguration.cs b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/Modularity/ExtensionPropertyConfiguration.cs
index eaad223cfa..8099f1fc14 100644
--- a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/Modularity/ExtensionPropertyConfiguration.cs
+++ b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/Modularity/ExtensionPropertyConfiguration.cs
@@ -23,8 +23,7 @@ public class ExtensionPropertyConfiguration : IHasNameWithLocalizableDisplayName
[NotNull]
public List> Validators { get; }
- [CanBeNull]
- public ILocalizableString DisplayName { get; set; }
+ public ILocalizableString? DisplayName { get; set; }
[NotNull]
public Dictionary Configuration { get; }
@@ -49,15 +48,13 @@ public class ExtensionPropertyConfiguration : IHasNameWithLocalizableDisplayName
///
/// Uses as the default value if was not set.
///
- [CanBeNull]
- public object DefaultValue { get; set; }
+ public object? DefaultValue { get; set; }
///
/// Used with the first priority to create the default value for the property.
/// Uses to the if this was not set.
///
- [CanBeNull]
- public Func DefaultValueFactory { get; set; }
+ public Func? DefaultValueFactory { get; set; }
public ExtensionPropertyConfiguration(
[NotNull] EntityExtensionConfiguration entityExtensionConfiguration,
@@ -80,7 +77,7 @@ public class ExtensionPropertyConfiguration : IHasNameWithLocalizableDisplayName
DefaultValue = TypeHelper.GetDefaultValue(Type);
}
- public object GetDefaultValue()
+ public object? GetDefaultValue()
{
return ExtensionPropertyHelper.GetDefaultValue(Type, DefaultValueFactory, DefaultValue);
}
diff --git a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/Modularity/ExtensionPropertyConfigurationExtensions.cs b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/Modularity/ExtensionPropertyConfigurationExtensions.cs
index 085e486756..0b826a0ec5 100644
--- a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/Modularity/ExtensionPropertyConfigurationExtensions.cs
+++ b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/Modularity/ExtensionPropertyConfigurationExtensions.cs
@@ -5,7 +5,7 @@ namespace Volo.Abp.ObjectExtending.Modularity;
public static class ExtensionPropertyConfigurationExtensions
{
- public static string GetLocalizationResourceNameOrNull(
+ public static string? GetLocalizationResourceNameOrNull(
this ExtensionPropertyConfiguration property)
{
if (property.DisplayName is LocalizableString localizableString)
@@ -16,7 +16,7 @@ public static class ExtensionPropertyConfigurationExtensions
return null;
}
- public static Type GetLocalizationResourceTypeOrNull(
+ public static Type? GetLocalizationResourceTypeOrNull(
this ExtensionPropertyConfiguration property)
{
if (property.DisplayName is LocalizableString localizableString)
diff --git a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/Modularity/ExtensionPropertyLookupConfiguration.cs b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/Modularity/ExtensionPropertyLookupConfiguration.cs
index 599ed7bed5..bd1cb61b20 100644
--- a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/Modularity/ExtensionPropertyLookupConfiguration.cs
+++ b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/Modularity/ExtensionPropertyLookupConfiguration.cs
@@ -4,7 +4,7 @@ namespace Volo.Abp.ObjectExtending.Modularity;
public class ExtensionPropertyLookupConfiguration
{
- public string Url { get; set; }
+ public string Url { get; set; } = default!;
///
/// Default value: "items".
diff --git a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/Modularity/ExtensionPropertyUiConfiguration.cs b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/Modularity/ExtensionPropertyUiConfiguration.cs
index 38b47b71ad..3c4a0e921f 100644
--- a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/Modularity/ExtensionPropertyUiConfiguration.cs
+++ b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/Modularity/ExtensionPropertyUiConfiguration.cs
@@ -4,6 +4,8 @@ namespace Volo.Abp.ObjectExtending.Modularity;
public class ExtensionPropertyUiConfiguration
{
+ public const int DefaultOrder = 1000;
+
[NotNull]
public ExtensionPropertyUiTableConfiguration OnTable { get; }
@@ -15,6 +17,8 @@ public class ExtensionPropertyUiConfiguration
[NotNull]
public ExtensionPropertyLookupConfiguration Lookup { get; set; }
+
+ public int Order { get; set; }
public ExtensionPropertyUiConfiguration()
{
@@ -22,5 +26,6 @@ public class ExtensionPropertyUiConfiguration
OnCreateForm = new ExtensionPropertyUiFormConfiguration();
OnEditForm = new ExtensionPropertyUiFormConfiguration();
Lookup = new ExtensionPropertyLookupConfiguration();
+ Order = DefaultOrder;
}
}
diff --git a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/Modularity/ModuleExtensionConfigurationHelper.cs b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/Modularity/ModuleExtensionConfigurationHelper.cs
index 642cd07a84..c1426e3833 100644
--- a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/Modularity/ModuleExtensionConfigurationHelper.cs
+++ b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/Modularity/ModuleExtensionConfigurationHelper.cs
@@ -29,9 +29,9 @@ public static class ModuleExtensionConfigurationHelper
public static void ApplyEntityConfigurationToApi(
string moduleName,
string objectName,
- Type[] getApiTypes = null,
- Type[] createApiTypes = null,
- Type[] updateApiTypes = null)
+ Type[]? getApiTypes = null,
+ Type[]? createApiTypes = null,
+ Type[]? updateApiTypes = null)
{
lock (SyncLock)
{
@@ -66,8 +66,8 @@ public static class ModuleExtensionConfigurationHelper
public static void ApplyEntityConfigurationToUi(
string moduleName,
string entityName,
- Type[] createFormTypes = null,
- Type[] editFormTypes = null)
+ Type[]? createFormTypes = null,
+ Type[]? editFormTypes = null)
{
lock (SyncLock)
{
@@ -96,12 +96,12 @@ public static class ModuleExtensionConfigurationHelper
public static void ApplyEntityConfigurations(
string moduleName,
string entityName,
- Type entityType = null,
- Type[] createFormTypes = null,
- Type[] editFormTypes = null,
- Type[] getApiTypes = null,
- Type[] createApiTypes = null,
- Type[] updateApiTypes = null)
+ Type? entityType = null,
+ Type[]? createFormTypes = null,
+ Type[]? editFormTypes = null,
+ Type[]? getApiTypes = null,
+ Type[]? createApiTypes = null,
+ Type[]? updateApiTypes = null)
{
lock (SyncLock)
{
@@ -174,6 +174,7 @@ public static class ModuleExtensionConfigurationHelper
property.DefaultValue = propertyConfig.DefaultValue;
property.DefaultValueFactory = propertyConfig.DefaultValueFactory;
property.Lookup = propertyConfig.UI.Lookup;
+ property.UI.Order = propertyConfig.UI.Order;
foreach (var configuration in propertyConfig.Configuration)
{
property.Configuration[configuration.Key] = configuration.Value;
diff --git a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ModuleObjectExtensionManagerExtensions.cs b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ModuleObjectExtensionManagerExtensions.cs
index f74b36f6ca..92a8f9ecd5 100644
--- a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ModuleObjectExtensionManagerExtensions.cs
+++ b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ModuleObjectExtensionManagerExtensions.cs
@@ -12,9 +12,9 @@ public static class ModuleObjectExtensionManagerExtensions
{
Check.NotNull(objectExtensionManager, nameof(objectExtensionManager));
- return objectExtensionManager.Configuration.GetOrAdd(
+ return (objectExtensionManager.Configuration.GetOrAdd(
ObjectExtensionManagerConfigurationKey,
_ => new ModuleExtensionConfigurationDictionary()
- ) as ModuleExtensionConfigurationDictionary;
+ ) as ModuleExtensionConfigurationDictionary)!;
}
}
diff --git a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ObjectExtensionInfo.cs b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ObjectExtensionInfo.cs
index 69b7123c50..c7ebe2f961 100644
--- a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ObjectExtensionInfo.cs
+++ b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ObjectExtensionInfo.cs
@@ -38,7 +38,7 @@ public class ObjectExtensionInfo
[NotNull]
public virtual ObjectExtensionInfo AddOrUpdateProperty(
[NotNull] string propertyName,
- [CanBeNull] Action configureAction = null)
+ Action? configureAction = null)
{
return AddOrUpdateProperty(
typeof(TProperty),
@@ -51,7 +51,7 @@ public class ObjectExtensionInfo
public virtual ObjectExtensionInfo AddOrUpdateProperty(
[NotNull] Type propertyType,
[NotNull] string propertyName,
- [CanBeNull] Action configureAction = null)
+ Action? configureAction = null)
{
Check.NotNull(propertyType, nameof(propertyType));
Check.NotNull(propertyName, nameof(propertyName));
@@ -69,13 +69,11 @@ public class ObjectExtensionInfo
[NotNull]
public virtual ImmutableList GetProperties()
{
- return Properties.OrderBy(t => t.Key)
- .Select(t => t.Value)
+ return Properties.OrderBy(t => t.Value.UI.Order).Select(t => t.Value)
.ToImmutableList();
}
- [CanBeNull]
- public virtual ObjectExtensionPropertyInfo GetPropertyOrNull(
+ public virtual ObjectExtensionPropertyInfo? GetPropertyOrNull(
[NotNull] string propertyName)
{
Check.NotNullOrEmpty(propertyName, nameof(propertyName));
diff --git a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ObjectExtensionManager.cs b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ObjectExtensionManager.cs
index ff62d1bd91..1d7ad836b4 100644
--- a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ObjectExtensionManager.cs
+++ b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ObjectExtensionManager.cs
@@ -24,7 +24,7 @@ public class ObjectExtensionManager
[NotNull]
public virtual ObjectExtensionManager AddOrUpdate(
- [CanBeNull] Action configureAction = null)
+ Action? configureAction = null)
{
return AddOrUpdate(typeof(TObject), configureAction);
}
@@ -32,7 +32,7 @@ public class ObjectExtensionManager
[NotNull]
public virtual ObjectExtensionManager AddOrUpdate(
[NotNull] Type[] types,
- [CanBeNull] Action configureAction = null)
+ Action? configureAction = null)
{
Check.NotNull(types, nameof(types));
@@ -47,7 +47,7 @@ public class ObjectExtensionManager
[NotNull]
public virtual ObjectExtensionManager AddOrUpdate(
[NotNull] Type type,
- [CanBeNull] Action configureAction = null)
+ Action? configureAction = null)
{
var extensionInfo = ObjectsExtensions.GetOrAdd(
type,
@@ -59,14 +59,12 @@ public class ObjectExtensionManager
return this;
}
- [CanBeNull]
- public virtual ObjectExtensionInfo GetOrNull()
+ public virtual ObjectExtensionInfo? GetOrNull()
{
return GetOrNull(typeof(TObject));
}
- [CanBeNull]
- public virtual ObjectExtensionInfo GetOrNull([NotNull] Type type)
+ public virtual ObjectExtensionInfo? GetOrNull([NotNull] Type type)
{
return ObjectsExtensions.GetOrDefault(type);
}
diff --git a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ObjectExtensionManagerExtensions.cs b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ObjectExtensionManagerExtensions.cs
index a9c5c8a76f..71c7d78353 100644
--- a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ObjectExtensionManagerExtensions.cs
+++ b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ObjectExtensionManagerExtensions.cs
@@ -13,7 +13,7 @@ public static class ObjectExtensionManagerExtensions
[NotNull] this ObjectExtensionManager objectExtensionManager,
[NotNull] Type[] objectTypes,
[NotNull] string propertyName,
- [CanBeNull] Action configureAction = null)
+ Action? configureAction = null)
{
return objectExtensionManager.AddOrUpdateProperty(
objectTypes,
@@ -26,7 +26,7 @@ public static class ObjectExtensionManagerExtensions
public static ObjectExtensionManager AddOrUpdateProperty(
[NotNull] this ObjectExtensionManager objectExtensionManager,
[NotNull] string propertyName,
- [CanBeNull] Action configureAction = null)
+ Action? configureAction = null)
where TObject : IHasExtraProperties
{
return objectExtensionManager.AddOrUpdateProperty(
@@ -43,7 +43,7 @@ public static class ObjectExtensionManagerExtensions
[NotNull] Type[] objectTypes,
[NotNull] Type propertyType,
[NotNull] string propertyName,
- [CanBeNull] Action configureAction = null)
+ Action? configureAction = null)
{
Check.NotNull(objectTypes, nameof(objectTypes));
@@ -66,7 +66,7 @@ public static class ObjectExtensionManagerExtensions
[NotNull] Type objectType,
[NotNull] Type propertyType,
[NotNull] string propertyName,
- [CanBeNull] Action configureAction = null)
+ Action? configureAction = null)
{
Check.NotNull(objectExtensionManager, nameof(objectExtensionManager));
@@ -82,7 +82,7 @@ public static class ObjectExtensionManagerExtensions
});
}
- public static ObjectExtensionPropertyInfo GetPropertyOrNull