diff --git a/Directory.Build.props b/Directory.Build.props
index 83a0f05a..99c2facf 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -5,6 +5,7 @@
2.5.3
2.0.11
0.8.2
+ 1.7.0
\ No newline at end of file
diff --git a/EShop.sln b/EShop.sln
index f003f77d..cd7f5691 100644
--- a/EShop.sln
+++ b/EShop.sln
@@ -341,6 +341,24 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyAbp.EShop.Plugins.Coupo
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyAbp.EShop.Orders.Plugins.Coupons", "plugins\Coupons\src\EasyAbp.EShop.Orders.Plugins.Coupons\EasyAbp.EShop.Orders.Plugins.Coupons.csproj", "{3C385657-8365-470F-9F4F-30F31F9FCA42}"
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Inventories", "Inventories", "{9AC27747-E175-487F-92C9-434DEE543273}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DaprActors", "DaprActors", "{6E6FE4B9-4117-4F57-B219-EE47E4046096}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyAbp.EShop.Products.DaprActorsInventory.Domain", "plugins\Inventories\DaprActors\src\EasyAbp.EShop.Products.DaprActorsInventory.Domain\EasyAbp.EShop.Products.DaprActorsInventory.Domain.csproj", "{6CD1A8B5-8AB7-4A31-8333-024A7FB602D1}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyAbp.EShop.Plugins.Inventories.DaprActors.Abstractions", "plugins\Inventories\DaprActors\src\EasyAbp.EShop.Plugins.Inventories.DaprActors.Abstractions\EasyAbp.EShop.Plugins.Inventories.DaprActors.Abstractions.csproj", "{CF4DE32D-9629-4C48-9BE8-5B83A1C27291}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyAbp.EShop.Plugins.Inventories.DaprActors", "plugins\Inventories\DaprActors\src\EasyAbp.EShop.Plugins.Inventories.DaprActors\EasyAbp.EShop.Plugins.Inventories.DaprActors.csproj", "{B6F3ACD5-463E-4455-A094-057A82941A94}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{F468A386-5660-4888-981A-6ECF15182D32}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{485204B1-7603-4EA0-B3A4-73CB89B0D5BC}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyAbp.EShop.Products.DaprActorsInventory.Domain.Tests", "plugins\Inventories\DaprActors\test\EasyAbp.EShop.Products.DaprActorsInventory.Domain.Tests\EasyAbp.EShop.Products.DaprActorsInventory.Domain.Tests.csproj", "{733C51A3-19C8-45C4-8B22-3FD40CAF4EFB}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyAbp.EShop.Plugins.Inventories.DaprActors.AspNetCore", "plugins\Inventories\DaprActors\src\EasyAbp.EShop.Plugins.Inventories.DaprActors.AspNetCore\EasyAbp.EShop.Plugins.Inventories.DaprActors.AspNetCore.csproj", "{3F0EA314-CCF4-4BB2-A8C1-79FAE4442884}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -895,6 +913,26 @@ Global
{3C385657-8365-470F-9F4F-30F31F9FCA42}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3C385657-8365-470F-9F4F-30F31F9FCA42}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3C385657-8365-470F-9F4F-30F31F9FCA42}.Release|Any CPU.Build.0 = Release|Any CPU
+ {6CD1A8B5-8AB7-4A31-8333-024A7FB602D1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {6CD1A8B5-8AB7-4A31-8333-024A7FB602D1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6CD1A8B5-8AB7-4A31-8333-024A7FB602D1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {6CD1A8B5-8AB7-4A31-8333-024A7FB602D1}.Release|Any CPU.Build.0 = Release|Any CPU
+ {CF4DE32D-9629-4C48-9BE8-5B83A1C27291}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {CF4DE32D-9629-4C48-9BE8-5B83A1C27291}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {CF4DE32D-9629-4C48-9BE8-5B83A1C27291}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {CF4DE32D-9629-4C48-9BE8-5B83A1C27291}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B6F3ACD5-463E-4455-A094-057A82941A94}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B6F3ACD5-463E-4455-A094-057A82941A94}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B6F3ACD5-463E-4455-A094-057A82941A94}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B6F3ACD5-463E-4455-A094-057A82941A94}.Release|Any CPU.Build.0 = Release|Any CPU
+ {733C51A3-19C8-45C4-8B22-3FD40CAF4EFB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {733C51A3-19C8-45C4-8B22-3FD40CAF4EFB}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {733C51A3-19C8-45C4-8B22-3FD40CAF4EFB}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {733C51A3-19C8-45C4-8B22-3FD40CAF4EFB}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3F0EA314-CCF4-4BB2-A8C1-79FAE4442884}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {3F0EA314-CCF4-4BB2-A8C1-79FAE4442884}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3F0EA314-CCF4-4BB2-A8C1-79FAE4442884}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {3F0EA314-CCF4-4BB2-A8C1-79FAE4442884}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -1065,6 +1103,15 @@ Global
{86CAD303-A0E5-42C9-89A5-61D9AAA4AD8F} = {4001814E-A67B-490D-9E13-2FB9A34B0A0B}
{B076C103-DF0B-464B-A9CB-4BE5CAFEE067} = {4001814E-A67B-490D-9E13-2FB9A34B0A0B}
{3C385657-8365-470F-9F4F-30F31F9FCA42} = {72F34527-9295-4F29-923E-4B075A4F31A2}
+ {9AC27747-E175-487F-92C9-434DEE543273} = {94CC5A11-DA0F-413C-96CA-01DB0FC426E0}
+ {6E6FE4B9-4117-4F57-B219-EE47E4046096} = {9AC27747-E175-487F-92C9-434DEE543273}
+ {F468A386-5660-4888-981A-6ECF15182D32} = {6E6FE4B9-4117-4F57-B219-EE47E4046096}
+ {B6F3ACD5-463E-4455-A094-057A82941A94} = {F468A386-5660-4888-981A-6ECF15182D32}
+ {CF4DE32D-9629-4C48-9BE8-5B83A1C27291} = {F468A386-5660-4888-981A-6ECF15182D32}
+ {6CD1A8B5-8AB7-4A31-8333-024A7FB602D1} = {F468A386-5660-4888-981A-6ECF15182D32}
+ {485204B1-7603-4EA0-B3A4-73CB89B0D5BC} = {6E6FE4B9-4117-4F57-B219-EE47E4046096}
+ {733C51A3-19C8-45C4-8B22-3FD40CAF4EFB} = {485204B1-7603-4EA0-B3A4-73CB89B0D5BC}
+ {3F0EA314-CCF4-4BB2-A8C1-79FAE4442884} = {F468A386-5660-4888-981A-6ECF15182D32}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {28315BFD-90E7-4E14-A2EA-F3D23AF4126F}
diff --git a/EShop.sln.DotSettings b/EShop.sln.DotSettings
index a1a9e93c..7b7d4176 100644
--- a/EShop.sln.DotSettings
+++ b/EShop.sln.DotSettings
@@ -21,4 +21,5 @@
False
SQL
True
+ True
True
\ No newline at end of file
diff --git a/docs/README.md b/docs/README.md
index f9e3ba8a..81da5c14 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -48,7 +48,7 @@ We have launched an online demo for this module: [https://eshop.samples.easyabp.
* Define a Product Group (optional)
* Product group is used to classify different types of products, so we can customize different behavior for them, for example, products of the "GiftCard" product group could automatically send the card number and password to the customer's mailbox.
- * EShop provides a [default product group](https://github.com/EasyAbp/EShop/blob/master/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/EShopProductsDomainModule.cs#L29-L36).
+ * EShop provides a [default product group](https://github.com/EasyAbp/EShop/blob/master/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/EShopProductsDomainModule.cs#L33-L37).
* Refer to the configuration of the default product group and define a new product group.
* Create a Product
@@ -102,6 +102,8 @@ We can customize some features to use EShop in complex application scenarios.
* Plugin modules
* Baskets
* Coupons
+ * Inventories
+ * [DaprActors](https://github.com/EasyAbp/EShop/tree/dev/plugins/Inventories/DaprActors)
## Roadmap
diff --git a/docs/plugins/inventories/dapr-actors/README.md b/docs/plugins/inventories/dapr-actors/README.md
new file mode 100644
index 00000000..3fa9e58b
--- /dev/null
+++ b/docs/plugins/inventories/dapr-actors/README.md
@@ -0,0 +1,38 @@
+# EShop.Plugins.Inventories.DaprActors
+
+[](https://abp.io)
+[](https://www.nuget.org/packages/EasyAbp.EShop.Plugins.Inventories.DaprActors.Abstractions)
+[](https://www.nuget.org/packages/EasyAbp.EShop.Plugins.Inventories.DaprActors.Abstractions)
+[](https://discord.gg/S6QaezrCRq)
+[](https://www.github.com/EasyAbp/EShop)
+
+EShop product-inventory implementation of [Dapr Actors](https://docs.dapr.io/developing-applications/building-blocks/actors/actors-overview).
+
+## Installation
+
+1. Install the following NuGet packages. ([see how](https://github.com/EasyAbp/EasyAbpGuide/blob/master/docs/How-To.md#add-nuget-packages))
+
+ * EasyAbp.EShop.Products.DaprActorsInventory.Domain _(install at EasyAbp.EShop.Products.Domain location)_
+ * EasyAbp.EShop.Plugins.Inventories.DaprActors.AspNetCore _(install at a host project to run Actors)_
+
+2. Add `DependsOn(typeof(EShopXxxModule))` attribute to configure the module dependencies. ([see how](https://github.com/EasyAbp/EasyAbpGuide/blob/master/docs/How-To.md#add-module-dependencies))
+
+## Usage
+
+1. Configure the DaprActors inventory provider as default.
+ ```csharp
+ Configure(options =>
+ {
+ // Configure as the default inventory provider
+ options.DefaultInventoryProviderName = "DaprActors";
+
+ // Configure as the default inventory provider for MyProductGroup
+ options.Groups.Configure(group =>
+ {
+ group.DefaultInventoryProviderName = "DaprActors";
+ });
+ });
+ ```
+ > Better to use `DaprActorsProductInventoryProvider.DaprActorsProductInventoryProviderName` instead of `"DaprActors"` as the provider name.
+
+2. Create a product and set `InventoryProviderName` to `DaprActors`. Then the product is specified to use the Dapr Actors inventory provider.
\ No newline at end of file
diff --git a/plugins/Inventories/DaprActors/README.md b/plugins/Inventories/DaprActors/README.md
new file mode 120000
index 00000000..6aba629a
--- /dev/null
+++ b/plugins/Inventories/DaprActors/README.md
@@ -0,0 +1 @@
+../../../docs/plugins/inventories/dapr-actors/README.md
\ No newline at end of file
diff --git a/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors.Abstractions/EasyAbp.EShop.Plugins.Inventories.DaprActors.Abstractions.csproj b/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors.Abstractions/EasyAbp.EShop.Plugins.Inventories.DaprActors.Abstractions.csproj
new file mode 100644
index 00000000..f5d2ebb7
--- /dev/null
+++ b/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors.Abstractions/EasyAbp.EShop.Plugins.Inventories.DaprActors.Abstractions.csproj
@@ -0,0 +1,18 @@
+
+
+
+
+
+ net6.0
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors.Abstractions/EasyAbp/EShop/Plugins/Inventories/DaprActors/EShopPluginsInventoriesDaprActorsAbstractionsModule.cs b/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors.Abstractions/EasyAbp/EShop/Plugins/Inventories/DaprActors/EShopPluginsInventoriesDaprActorsAbstractionsModule.cs
new file mode 100644
index 00000000..37b93cf2
--- /dev/null
+++ b/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors.Abstractions/EasyAbp/EShop/Plugins/Inventories/DaprActors/EShopPluginsInventoriesDaprActorsAbstractionsModule.cs
@@ -0,0 +1,11 @@
+using EasyAbp.EShop.Products;
+using Volo.Abp.Modularity;
+
+namespace EasyAbp.EShop.Plugins.Inventories.DaprActors;
+
+[DependsOn(
+ typeof(EShopProductsDomainSharedModule)
+)]
+public class EShopPluginsInventoriesDaprActorsAbstractionsModule : AbpModule
+{
+}
\ No newline at end of file
diff --git a/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors.Abstractions/EasyAbp/EShop/Plugins/Inventories/DaprActors/IInventoryActor.cs b/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors.Abstractions/EasyAbp/EShop/Plugins/Inventories/DaprActors/IInventoryActor.cs
new file mode 100644
index 00000000..714904b5
--- /dev/null
+++ b/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors.Abstractions/EasyAbp/EShop/Plugins/Inventories/DaprActors/IInventoryActor.cs
@@ -0,0 +1,13 @@
+using System.Threading.Tasks;
+using Dapr.Actors;
+
+namespace EasyAbp.EShop.Plugins.Inventories.DaprActors;
+
+public interface IInventoryActor : IActor
+{
+ Task GetInventoryStateAsync();
+
+ Task IncreaseInventoryAsync(int quantity, bool decreaseSold);
+
+ Task ReduceInventoryAsync(int quantity, bool increaseSold);
+}
\ No newline at end of file
diff --git a/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors.Abstractions/EasyAbp/EShop/Plugins/Inventories/DaprActors/InventoryStateModel.cs b/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors.Abstractions/EasyAbp/EShop/Plugins/Inventories/DaprActors/InventoryStateModel.cs
new file mode 100644
index 00000000..96f0ef28
--- /dev/null
+++ b/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors.Abstractions/EasyAbp/EShop/Plugins/Inventories/DaprActors/InventoryStateModel.cs
@@ -0,0 +1,8 @@
+namespace EasyAbp.EShop.Plugins.Inventories.DaprActors;
+
+public class InventoryStateModel
+{
+ public int Inventory { get; set; }
+
+ public long Sold { get; set; }
+}
\ No newline at end of file
diff --git a/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors.Abstractions/FodyWeavers.xml b/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors.Abstractions/FodyWeavers.xml
new file mode 100644
index 00000000..1715698c
--- /dev/null
+++ b/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors.Abstractions/FodyWeavers.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors.Abstractions/FodyWeavers.xsd b/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors.Abstractions/FodyWeavers.xsd
new file mode 100644
index 00000000..ffa6fc4b
--- /dev/null
+++ b/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors.Abstractions/FodyWeavers.xsd
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.
+
+
+
+
+ A comma-separated list of error codes that can be safely ignored in assembly verification.
+
+
+
+
+ 'false' to turn off automatic generation of the XML Schema file.
+
+
+
+
+
\ No newline at end of file
diff --git a/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors.AspNetCore/EasyAbp.EShop.Plugins.Inventories.DaprActors.AspNetCore.csproj b/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors.AspNetCore/EasyAbp.EShop.Plugins.Inventories.DaprActors.AspNetCore.csproj
new file mode 100644
index 00000000..9a6f080b
--- /dev/null
+++ b/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors.AspNetCore/EasyAbp.EShop.Plugins.Inventories.DaprActors.AspNetCore.csproj
@@ -0,0 +1,19 @@
+
+
+
+
+
+ net6.0
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors.AspNetCore/EasyAbp/EShop/Plugins/Inventories/DaprActors/EShopPluginsInventoriesDaprActorsAspNetCoreModule.cs b/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors.AspNetCore/EasyAbp/EShop/Plugins/Inventories/DaprActors/EShopPluginsInventoriesDaprActorsAspNetCoreModule.cs
new file mode 100644
index 00000000..84d1eca1
--- /dev/null
+++ b/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors.AspNetCore/EasyAbp/EShop/Plugins/Inventories/DaprActors/EShopPluginsInventoriesDaprActorsAspNetCoreModule.cs
@@ -0,0 +1,29 @@
+using EasyAbp.EShop.Products;
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Routing;
+using Microsoft.Extensions.DependencyInjection;
+using Volo.Abp.AspNetCore;
+using Volo.Abp.Modularity;
+
+namespace EasyAbp.EShop.Plugins.Inventories.DaprActors;
+
+[DependsOn(
+ typeof(AbpAspNetCoreModule),
+ typeof(EShopProductsDomainSharedModule)
+)]
+public class EShopPluginsInventoriesDaprActorsAspNetCoreModule : AbpModule
+{
+ public override void ConfigureServices(ServiceConfigurationContext context)
+ {
+ context.Services.AddActors(options => { options.Actors.RegisterActor(); });
+
+ Configure(options =>
+ {
+ options.EndpointConfigureActions.Add(ctx =>
+ {
+ // Register actors handlers that interface with the Dapr runtime.
+ ctx.Endpoints.MapActorsHandlers();
+ });
+ });
+ }
+}
\ No newline at end of file
diff --git a/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors/EasyAbp.EShop.Plugins.Inventories.DaprActors.csproj b/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors/EasyAbp.EShop.Plugins.Inventories.DaprActors.csproj
new file mode 100644
index 00000000..4b5cd92d
--- /dev/null
+++ b/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors/EasyAbp.EShop.Plugins.Inventories.DaprActors.csproj
@@ -0,0 +1,18 @@
+
+
+
+
+
+ net6.0
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors/EasyAbp/EShop/Plugins/Inventories/DaprActors/EShopPluginsInventoriesDaprActorsModule.cs b/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors/EasyAbp/EShop/Plugins/Inventories/DaprActors/EShopPluginsInventoriesDaprActorsModule.cs
new file mode 100644
index 00000000..0b59cb9b
--- /dev/null
+++ b/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors/EasyAbp/EShop/Plugins/Inventories/DaprActors/EShopPluginsInventoriesDaprActorsModule.cs
@@ -0,0 +1,10 @@
+using Volo.Abp.Modularity;
+
+namespace EasyAbp.EShop.Plugins.Inventories.DaprActors;
+
+[DependsOn(
+ typeof(EShopPluginsInventoriesDaprActorsAbstractionsModule)
+)]
+public class EShopPluginsInventoriesDaprActorsModule : AbpModule
+{
+}
\ No newline at end of file
diff --git a/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors/EasyAbp/EShop/Plugins/Inventories/DaprActors/InventoryActor.cs b/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors/EasyAbp/EShop/Plugins/Inventories/DaprActors/InventoryActor.cs
new file mode 100644
index 00000000..eb8e7345
--- /dev/null
+++ b/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors/EasyAbp/EShop/Plugins/Inventories/DaprActors/InventoryActor.cs
@@ -0,0 +1,78 @@
+using System.Threading.Tasks;
+using Dapr;
+using Dapr.Actors.Runtime;
+
+namespace EasyAbp.EShop.Plugins.Inventories.DaprActors;
+
+public class InventoryActor : Actor, IInventoryActor
+{
+ public static string InventoryStateName { get; set; } = "i";
+
+ public InventoryActor(ActorHost host) : base(host)
+ {
+ }
+
+ protected override async Task OnActivateAsync()
+ {
+ await StateManager.TryAddStateAsync(InventoryStateName, new InventoryStateModel());
+ }
+
+ public virtual async Task GetInventoryStateAsync()
+ {
+ return await StateManager.GetStateAsync(InventoryStateName);
+ }
+
+ public virtual async Task IncreaseInventoryAsync(int quantity, bool decreaseSold)
+ {
+ var state = await GetInventoryStateAsync();
+
+ InternalIncreaseInventory(state, quantity, decreaseSold);
+ }
+
+ public async Task ReduceInventoryAsync(int quantity, bool increaseSold)
+ {
+ var state = await GetInventoryStateAsync();
+
+ InternalReduceInventory(state, quantity, increaseSold);
+ }
+
+ protected virtual void InternalIncreaseInventory(InventoryStateModel stateModel, int quantity, bool decreaseSold)
+ {
+ if (quantity < 0)
+ {
+ throw new DaprException("Quantity should not be less than 0.");
+ }
+
+ if (decreaseSold && stateModel.Sold - quantity < 0)
+ {
+ throw new DaprException("Target Sold cannot be less than 0.");
+ }
+
+ stateModel.Inventory = checked(stateModel.Inventory + quantity);
+
+ if (decreaseSold)
+ {
+ stateModel.Sold -= quantity;
+ }
+ }
+
+ protected virtual void InternalReduceInventory(InventoryStateModel stateModel, int quantity, bool increaseSold)
+ {
+ if (quantity < 0)
+ {
+ throw new DaprException("Quantity should not be less than 0.");
+ }
+
+ if (quantity > stateModel.Inventory)
+ {
+ throw new DaprException("Insufficient inventory.");
+ }
+
+ if (increaseSold)
+ {
+ stateModel.Sold = checked(stateModel.Sold + quantity);
+ }
+
+ stateModel.Inventory -= quantity;
+ }
+}
\ No newline at end of file
diff --git a/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors/FodyWeavers.xml b/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors/FodyWeavers.xml
new file mode 100644
index 00000000..1715698c
--- /dev/null
+++ b/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors/FodyWeavers.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors/FodyWeavers.xsd b/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors/FodyWeavers.xsd
new file mode 100644
index 00000000..ffa6fc4b
--- /dev/null
+++ b/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors/FodyWeavers.xsd
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.
+
+
+
+
+ A comma-separated list of error codes that can be safely ignored in assembly verification.
+
+
+
+
+ 'false' to turn off automatic generation of the XML Schema file.
+
+
+
+
+
\ No newline at end of file
diff --git a/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Products.DaprActorsInventory.Domain/EasyAbp.EShop.Products.DaprActorsInventory.Domain.csproj b/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Products.DaprActorsInventory.Domain/EasyAbp.EShop.Products.DaprActorsInventory.Domain.csproj
new file mode 100644
index 00000000..93c911a8
--- /dev/null
+++ b/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Products.DaprActorsInventory.Domain/EasyAbp.EShop.Products.DaprActorsInventory.Domain.csproj
@@ -0,0 +1,15 @@
+
+
+
+
+
+ net6.0
+
+
+
+
+
+
+
+
+
diff --git a/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Products.DaprActorsInventory.Domain/EasyAbp/EShop/Products/DaprActorsInventory/DaprActorsProductInventoryProvider.cs b/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Products.DaprActorsInventory.Domain/EasyAbp/EShop/Products/DaprActorsInventory/DaprActorsProductInventoryProvider.cs
new file mode 100644
index 00000000..5c2561c4
--- /dev/null
+++ b/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Products.DaprActorsInventory.Domain/EasyAbp/EShop/Products/DaprActorsInventory/DaprActorsProductInventoryProvider.cs
@@ -0,0 +1,113 @@
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Dapr.Actors;
+using EasyAbp.EShop.Plugins.Inventories.DaprActors;
+using EasyAbp.EShop.Products.ProductInventories;
+using Microsoft.Extensions.Logging;
+using Volo.Abp.DependencyInjection;
+
+namespace EasyAbp.EShop.Products.DaprActorsInventory;
+
+public class DaprActorsProductInventoryProvider : IProductInventoryProvider, ITransientDependency
+{
+ public static string DaprActorsProductInventoryProviderName { get; set; } = "DaprActors";
+ public static string DaprActorsProductInventoryProviderDisplayName { get; set; } = "DaprActors";
+ public static string DaprActorsProductInventoryProviderDescription { get; set; } = "DaprActors";
+
+ public string InventoryProviderName { get; } = DaprActorsProductInventoryProviderName;
+
+ public static string ActorType { get; set; } = "InventoryActor";
+
+ private readonly ILogger _logger;
+ protected IInventoryActorProvider InventoryActorProvider { get; }
+
+ public DaprActorsProductInventoryProvider(
+ IInventoryActorProvider inventoryActorProvider,
+ ILogger logger)
+ {
+ InventoryActorProvider = inventoryActorProvider;
+ _logger = logger;
+ }
+
+ public virtual async Task GetInventoryDataAsync(InventoryQueryModel model)
+ {
+ var actor = await GetActorAsync(model);
+
+ var stateModel = await actor.GetInventoryStateAsync();
+
+ return new InventoryDataModel
+ {
+ Inventory = stateModel.Inventory,
+ Sold = stateModel.Sold
+ };
+ }
+
+ public virtual async Task> GetSkuIdInventoryDataMappingAsync(
+ IList models)
+ {
+ var result = new Dictionary();
+
+ foreach (var model in models)
+ {
+ result.Add(model.ProductSkuId, await GetInventoryDataAsync(model));
+ }
+
+ return result;
+ }
+
+ public virtual async Task TryIncreaseInventoryAsync(InventoryQueryModel model, int quantity,
+ bool decreaseSold)
+ {
+ var actor = await GetActorAsync(model);
+
+ try
+ {
+ await actor.IncreaseInventoryAsync(quantity, decreaseSold);
+ }
+ catch (Exception e)
+ {
+ _logger.LogError("Actor threw: {Message}", e.Message);
+
+ return false;
+ }
+
+ return true;
+ }
+
+ public virtual async Task TryReduceInventoryAsync(InventoryQueryModel model, int quantity, bool increaseSold)
+ {
+ var actor = await GetActorAsync(model);
+
+ var stateModel = await actor.GetInventoryStateAsync();
+
+ if (stateModel.Inventory < quantity)
+ {
+ return false;
+ }
+
+ try
+ {
+ await actor.ReduceInventoryAsync(quantity, increaseSold);
+ }
+ catch (Exception e)
+ {
+ _logger.LogError("Actor threw: {Message}", e.Message);
+
+ return false;
+ }
+
+ return true;
+ }
+
+ protected virtual async Task GetActorAsync(InventoryQueryModel model)
+ {
+ return await InventoryActorProvider.GetAsync(GetActorId(model), ActorType);
+ }
+
+ protected virtual ActorId GetActorId(InventoryQueryModel model)
+ {
+ return new ActorId(
+ $"eshop_inventory_{(model.TenantId.HasValue ? model.TenantId.Value : "host")}_{model.ProductSkuId}");
+ }
+}
\ No newline at end of file
diff --git a/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Products.DaprActorsInventory.Domain/EasyAbp/EShop/Products/DaprActorsInventory/EShopProductsDaprActorsInventoryDomainModule.cs b/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Products.DaprActorsInventory.Domain/EasyAbp/EShop/Products/DaprActorsInventory/EShopProductsDaprActorsInventoryDomainModule.cs
new file mode 100644
index 00000000..3c9dc09a
--- /dev/null
+++ b/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Products.DaprActorsInventory.Domain/EasyAbp/EShop/Products/DaprActorsInventory/EShopProductsDaprActorsInventoryDomainModule.cs
@@ -0,0 +1,28 @@
+using EasyAbp.EShop.Plugins.Inventories.DaprActors;
+using EasyAbp.EShop.Products.Options;
+using Volo.Abp.Modularity;
+
+namespace EasyAbp.EShop.Products.DaprActorsInventory;
+
+[DependsOn(
+ typeof(EShopProductsDomainModule),
+ typeof(EShopPluginsInventoriesDaprActorsAbstractionsModule)
+)]
+public class EShopProductsDaprActorsInventoryDomainModule : AbpModule
+{
+ public override void ConfigureServices(ServiceConfigurationContext context)
+ {
+ Configure(options =>
+ {
+ options.InventoryProviders.Configure(
+ DaprActorsProductInventoryProvider.DaprActorsProductInventoryProviderName, provider =>
+ {
+ provider.DisplayName =
+ DaprActorsProductInventoryProvider.DaprActorsProductInventoryProviderDisplayName;
+ provider.Description = DaprActorsProductInventoryProvider
+ .DaprActorsProductInventoryProviderDescription;
+ provider.ProviderType = typeof(DaprActorsProductInventoryProvider);
+ });
+ });
+ }
+}
\ No newline at end of file
diff --git a/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Products.DaprActorsInventory.Domain/EasyAbp/EShop/Products/DaprActorsInventory/IInventoryActorProvider.cs b/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Products.DaprActorsInventory.Domain/EasyAbp/EShop/Products/DaprActorsInventory/IInventoryActorProvider.cs
new file mode 100644
index 00000000..8c0791fd
--- /dev/null
+++ b/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Products.DaprActorsInventory.Domain/EasyAbp/EShop/Products/DaprActorsInventory/IInventoryActorProvider.cs
@@ -0,0 +1,11 @@
+using System.Threading.Tasks;
+using Dapr.Actors;
+using EasyAbp.EShop.Plugins.Inventories.DaprActors;
+using JetBrains.Annotations;
+
+namespace EasyAbp.EShop.Products.DaprActorsInventory;
+
+public interface IInventoryActorProvider
+{
+ Task GetAsync(ActorId actorId, [NotNull] string actorType);
+}
\ No newline at end of file
diff --git a/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Products.DaprActorsInventory.Domain/EasyAbp/EShop/Products/DaprActorsInventory/InventoryActorProvider.cs b/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Products.DaprActorsInventory.Domain/EasyAbp/EShop/Products/DaprActorsInventory/InventoryActorProvider.cs
new file mode 100644
index 00000000..11d016ae
--- /dev/null
+++ b/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Products.DaprActorsInventory.Domain/EasyAbp/EShop/Products/DaprActorsInventory/InventoryActorProvider.cs
@@ -0,0 +1,15 @@
+using System.Threading.Tasks;
+using Dapr.Actors;
+using Dapr.Actors.Client;
+using EasyAbp.EShop.Plugins.Inventories.DaprActors;
+using Volo.Abp.DependencyInjection;
+
+namespace EasyAbp.EShop.Products.DaprActorsInventory;
+
+public class InventoryActorProvider : IInventoryActorProvider, ITransientDependency
+{
+ public virtual Task GetAsync(ActorId actorId, string actorType)
+ {
+ return Task.FromResult(ActorProxy.Create(actorId, actorType));
+ }
+}
\ No newline at end of file
diff --git a/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Products.DaprActorsInventory.Domain/FodyWeavers.xml b/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Products.DaprActorsInventory.Domain/FodyWeavers.xml
new file mode 100644
index 00000000..1715698c
--- /dev/null
+++ b/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Products.DaprActorsInventory.Domain/FodyWeavers.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Products.DaprActorsInventory.Domain/FodyWeavers.xsd b/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Products.DaprActorsInventory.Domain/FodyWeavers.xsd
new file mode 100644
index 00000000..ffa6fc4b
--- /dev/null
+++ b/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Products.DaprActorsInventory.Domain/FodyWeavers.xsd
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.
+
+
+
+
+ A comma-separated list of error codes that can be safely ignored in assembly verification.
+
+
+
+
+ 'false' to turn off automatic generation of the XML Schema file.
+
+
+
+
+
\ No newline at end of file
diff --git a/plugins/Inventories/DaprActors/test/EasyAbp.EShop.Products.DaprActorsInventory.Domain.Tests/DaprActorsProductInventoryProviderTests.cs b/plugins/Inventories/DaprActors/test/EasyAbp.EShop.Products.DaprActorsInventory.Domain.Tests/DaprActorsProductInventoryProviderTests.cs
new file mode 100644
index 00000000..ce701107
--- /dev/null
+++ b/plugins/Inventories/DaprActors/test/EasyAbp.EShop.Products.DaprActorsInventory.Domain.Tests/DaprActorsProductInventoryProviderTests.cs
@@ -0,0 +1,48 @@
+using System.Threading.Tasks;
+using EasyAbp.EShop.Products.ProductInventories;
+using Microsoft.Extensions.DependencyInjection;
+using Shouldly;
+using Xunit;
+
+namespace EasyAbp.EShop.Products.DaprActorsInventory.Domain;
+
+public class DaprActorsProductInventoryProviderTests : ProductsDaprActorsInventoryTestBase
+{
+ [Fact]
+ public async Task Should_Get_Inventory()
+ {
+ var inventoryProvider = ServiceProvider.GetRequiredService();
+
+ var inventoryDataModel = await inventoryProvider.GetInventoryDataAsync(new InventoryQueryModel());
+
+ inventoryDataModel.ShouldNotBeNull();
+ inventoryDataModel.Inventory.ShouldBe(100);
+ inventoryDataModel.Sold.ShouldBe(0);
+ }
+
+ [Fact]
+ public async Task Should_Change_Inventory()
+ {
+ var inventoryProvider = ServiceProvider.GetRequiredService();
+
+ var result = await inventoryProvider.TryReduceInventoryAsync(new InventoryQueryModel(), 2, true);
+
+ result.ShouldBeTrue();
+
+ var inventoryDataModel = await inventoryProvider.GetInventoryDataAsync(new InventoryQueryModel());
+
+ inventoryDataModel.ShouldNotBeNull();
+ inventoryDataModel.Inventory.ShouldBe(98);
+ inventoryDataModel.Sold.ShouldBe(2);
+
+ result = await inventoryProvider.TryIncreaseInventoryAsync(new InventoryQueryModel(), 1, true);
+
+ result.ShouldBeTrue();
+
+ inventoryDataModel = await inventoryProvider.GetInventoryDataAsync(new InventoryQueryModel());
+
+ inventoryDataModel.ShouldNotBeNull();
+ inventoryDataModel.Inventory.ShouldBe(99);
+ inventoryDataModel.Sold.ShouldBe(1);
+ }
+}
\ No newline at end of file
diff --git a/plugins/Inventories/DaprActors/test/EasyAbp.EShop.Products.DaprActorsInventory.Domain.Tests/EShopProductsDaprActorsInventoryDomainTestModule.cs b/plugins/Inventories/DaprActors/test/EasyAbp.EShop.Products.DaprActorsInventory.Domain.Tests/EShopProductsDaprActorsInventoryDomainTestModule.cs
new file mode 100644
index 00000000..8b3c22fb
--- /dev/null
+++ b/plugins/Inventories/DaprActors/test/EasyAbp.EShop.Products.DaprActorsInventory.Domain.Tests/EShopProductsDaprActorsInventoryDomainTestModule.cs
@@ -0,0 +1,16 @@
+using Volo.Abp;
+using Volo.Abp.Authorization;
+using Volo.Abp.Autofac;
+using Volo.Abp.Modularity;
+
+namespace EasyAbp.EShop.Products.DaprActorsInventory.Domain;
+
+[DependsOn(
+ typeof(AbpAutofacModule),
+ typeof(AbpTestBaseModule),
+ typeof(AbpAuthorizationModule),
+ typeof(EShopProductsDaprActorsInventoryDomainModule)
+)]
+public class EShopProductsDaprActorsInventoryDomainTestModule : AbpModule
+{
+}
\ No newline at end of file
diff --git a/plugins/Inventories/DaprActors/test/EasyAbp.EShop.Products.DaprActorsInventory.Domain.Tests/EasyAbp.EShop.Products.DaprActorsInventory.Domain.Tests.csproj b/plugins/Inventories/DaprActors/test/EasyAbp.EShop.Products.DaprActorsInventory.Domain.Tests/EasyAbp.EShop.Products.DaprActorsInventory.Domain.Tests.csproj
new file mode 100644
index 00000000..5fc3de69
--- /dev/null
+++ b/plugins/Inventories/DaprActors/test/EasyAbp.EShop.Products.DaprActorsInventory.Domain.Tests/EasyAbp.EShop.Products.DaprActorsInventory.Domain.Tests.csproj
@@ -0,0 +1,24 @@
+
+
+
+ net6.0
+ EasyAbp.EShop.Products.DaprActorsInventory.Domain
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/plugins/Inventories/DaprActors/test/EasyAbp.EShop.Products.DaprActorsInventory.Domain.Tests/FakeInventoryActor.cs b/plugins/Inventories/DaprActors/test/EasyAbp.EShop.Products.DaprActorsInventory.Domain.Tests/FakeInventoryActor.cs
new file mode 100644
index 00000000..58ae0129
--- /dev/null
+++ b/plugins/Inventories/DaprActors/test/EasyAbp.EShop.Products.DaprActorsInventory.Domain.Tests/FakeInventoryActor.cs
@@ -0,0 +1,43 @@
+using System.Threading.Tasks;
+using EasyAbp.EShop.Plugins.Inventories.DaprActors;
+using Volo.Abp.DependencyInjection;
+
+namespace EasyAbp.EShop.Products.DaprActorsInventory.Domain;
+
+public class FakeInventoryActor : IInventoryActor, ITransientDependency
+{
+ private InventoryStateModel StateModel { get; } = new()
+ {
+ Inventory = 100,
+ Sold = 0
+ };
+
+ public Task GetInventoryStateAsync()
+ {
+ return Task.FromResult(StateModel);
+ }
+
+ public Task IncreaseInventoryAsync(int quantity, bool decreaseSold)
+ {
+ StateModel.Inventory += quantity;
+
+ if (decreaseSold)
+ {
+ StateModel.Sold -= quantity;
+ }
+
+ return Task.CompletedTask;
+ }
+
+ public Task ReduceInventoryAsync(int quantity, bool increaseSold)
+ {
+ StateModel.Inventory -= quantity;
+
+ if (increaseSold)
+ {
+ StateModel.Sold += quantity;
+ }
+
+ return Task.CompletedTask;
+ }
+}
\ No newline at end of file
diff --git a/plugins/Inventories/DaprActors/test/EasyAbp.EShop.Products.DaprActorsInventory.Domain.Tests/ProductsDaprActorsInventoryTestBase.cs b/plugins/Inventories/DaprActors/test/EasyAbp.EShop.Products.DaprActorsInventory.Domain.Tests/ProductsDaprActorsInventoryTestBase.cs
new file mode 100644
index 00000000..55c5d3fc
--- /dev/null
+++ b/plugins/Inventories/DaprActors/test/EasyAbp.EShop.Products.DaprActorsInventory.Domain.Tests/ProductsDaprActorsInventoryTestBase.cs
@@ -0,0 +1,61 @@
+using System;
+using System.Threading.Tasks;
+using Microsoft.Extensions.DependencyInjection;
+using Volo.Abp;
+using Volo.Abp.Modularity;
+using Volo.Abp.Testing;
+using Volo.Abp.Uow;
+
+namespace EasyAbp.EShop.Products.DaprActorsInventory.Domain
+{
+ /* All test classes are derived from this class, directly or indirectly. */
+ public abstract class
+ ProductsDaprActorsInventoryTestBase : AbpIntegratedTest
+ {
+ protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options)
+ {
+ options.UseAutofac();
+ }
+
+ protected virtual Task WithUnitOfWorkAsync(Func func)
+ {
+ return WithUnitOfWorkAsync(new AbpUnitOfWorkOptions(), func);
+ }
+
+ protected virtual async Task WithUnitOfWorkAsync(AbpUnitOfWorkOptions options, Func action)
+ {
+ using (var scope = ServiceProvider.CreateScope())
+ {
+ var uowManager = scope.ServiceProvider.GetRequiredService();
+
+ using (var uow = uowManager.Begin(options))
+ {
+ await action();
+
+ await uow.CompleteAsync();
+ }
+ }
+ }
+
+ protected virtual Task WithUnitOfWorkAsync(Func> func)
+ {
+ return WithUnitOfWorkAsync(new AbpUnitOfWorkOptions(), func);
+ }
+
+ protected virtual async Task WithUnitOfWorkAsync(AbpUnitOfWorkOptions options,
+ Func> func)
+ {
+ using (var scope = ServiceProvider.CreateScope())
+ {
+ var uowManager = scope.ServiceProvider.GetRequiredService();
+
+ using (var uow = uowManager.Begin(options))
+ {
+ var result = await func();
+ await uow.CompleteAsync();
+ return result;
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/plugins/Inventories/DaprActors/test/EasyAbp.EShop.Products.DaprActorsInventory.Domain.Tests/TestInventoryActorProvider.cs b/plugins/Inventories/DaprActors/test/EasyAbp.EShop.Products.DaprActorsInventory.Domain.Tests/TestInventoryActorProvider.cs
new file mode 100644
index 00000000..db26bdad
--- /dev/null
+++ b/plugins/Inventories/DaprActors/test/EasyAbp.EShop.Products.DaprActorsInventory.Domain.Tests/TestInventoryActorProvider.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Threading.Tasks;
+using Dapr.Actors;
+using EasyAbp.EShop.Plugins.Inventories.DaprActors;
+using Microsoft.Extensions.DependencyInjection;
+using Volo.Abp.DependencyInjection;
+
+namespace EasyAbp.EShop.Products.DaprActorsInventory.Domain;
+
+[Dependency(ReplaceServices = true)]
+public class TestInventoryActorProvider : IInventoryActorProvider, ITransientDependency
+{
+ private IInventoryActor Actor { get; set; }
+
+ private readonly IServiceProvider _serviceProvider;
+
+ public TestInventoryActorProvider(IServiceProvider serviceProvider)
+ {
+ _serviceProvider = serviceProvider;
+ }
+
+ public Task GetAsync(ActorId actorId, string actorType)
+ {
+ return Task.FromResult(Actor ??= _serviceProvider.GetRequiredService());
+ }
+}
\ No newline at end of file