diff --git a/docs/en/tutorials/modular-crm/images/abp-studio-import-module-ordering.png b/docs/en/tutorials/modular-crm/images/abp-studio-import-module-ordering.png index 8956033762..98b7ac5d66 100644 Binary files a/docs/en/tutorials/modular-crm/images/abp-studio-import-module-ordering.png and b/docs/en/tutorials/modular-crm/images/abp-studio-import-module-ordering.png differ diff --git a/docs/en/tutorials/modular-crm/images/abp-studio-imports-and-dependencies.png b/docs/en/tutorials/modular-crm/images/abp-studio-imports-and-dependencies.png index 30d484ba6b..3576d46a41 100644 Binary files a/docs/en/tutorials/modular-crm/images/abp-studio-imports-and-dependencies.png and b/docs/en/tutorials/modular-crm/images/abp-studio-imports-and-dependencies.png differ diff --git a/docs/en/tutorials/modular-crm/images/abp-studio-install-module-dialog-for-ordering.png b/docs/en/tutorials/modular-crm/images/abp-studio-install-module-dialog-for-ordering.png index 7ecb6b6262..25d19aea73 100644 Binary files a/docs/en/tutorials/modular-crm/images/abp-studio-install-module-dialog-for-ordering.png and b/docs/en/tutorials/modular-crm/images/abp-studio-install-module-dialog-for-ordering.png differ diff --git a/docs/en/tutorials/modular-crm/images/visual-studio-order-event-handler.png b/docs/en/tutorials/modular-crm/images/visual-studio-order-event-handler.png index cae742abb3..5f34e01d69 100644 Binary files a/docs/en/tutorials/modular-crm/images/visual-studio-order-event-handler.png and b/docs/en/tutorials/modular-crm/images/visual-studio-order-event-handler.png differ diff --git a/docs/en/tutorials/modular-crm/part-07.md b/docs/en/tutorials/modular-crm/part-07.md index 4bcace4239..e31f5c1e83 100644 --- a/docs/en/tutorials/modular-crm/part-07.md +++ b/docs/en/tutorials/modular-crm/part-07.md @@ -29,7 +29,7 @@ We will use the distributed event bus since we will use messaging (events) betwe ## Publishing an Event -In the example scenario, we want to publish an event when a new order is placed. The Ordering module will publish the event since it knows when a new order is placed. The Products module will subscribe to that event and get notified when a new order is placed. This will decrease the stock count of the product related to the new order. The scenario is pretty simple; let's implement it. +In the example scenario, we want to publish an event when a new order is placed. The Ordering module will publish the event since it knows when a new order is placed. The Catalog module will subscribe to that event and get notified when a new order is placed. This will decrease the stock count of the product related to the new order. The scenario is pretty simple; let's implement it. ### Defining the Event Class @@ -42,13 +42,12 @@ We've placed the `OrderPlacedEto` class inside the `ModularCrm.Ordering.Contract ````csharp using System; -namespace ModularCrm.Ordering.Events +namespace ModularCrm.Ordering.Events; + +public class OrderPlacedEto { - public class OrderPlacedEto - { - public string CustomerName { get; set; } - public Guid ProductId { get; set; } - } + public string CustomerName { get; set; } = null!; + public Guid ProductId { get; set; } } ```` @@ -69,6 +68,7 @@ using ModularCrm.Ordering.Entities; using ModularCrm.Products.Integration; using Volo.Abp.Domain.Repositories; using Volo.Abp.EventBus.Distributed; +using ModularCrm.Ordering.Contracts.Services; namespace ModularCrm.Ordering.Services; @@ -136,13 +136,13 @@ The `OrderAppService.CreateAsync` method creates a new `Order` entity, saves it ## Subscribing to an Event -This section will subscribe to the `OrderPlacedEto` event in the Products module and decrease the related product's stock count once a new order is placed. +This section will subscribe to the `OrderPlacedEto` event in the Catalog module and decrease the related product's stock count once a new order is placed. -### Adding a Reference to the `ModularCrm.Ordering.Contracts` Package +### Adding a Reference of the `ModularCrm.Ordering.Contracts` Package -Since the `OrderPlacedEto` class is in the `ModularCrm.Ordering.Contracts` project, we must add that package's reference to the Products module. This time, we will use the *Import Module* feature of ABP Studio (as an alternative to the approach we used in the *Adding a Reference to the `ModularCrm.Products.Application.Contracts` Package* section of the [previous part](part-06.md)). +Since the `OrderPlacedEto` class is in the `ModularCrm.Ordering.Contracts` project, we must add that package's reference to the Catalog module. This time, we will use the *Import Module* feature of ABP Studio (as an alternative to the approach we used in the *Adding a Reference to the `ModularCrm.Catalog.Contracts` Package* section of the [previous part](part-06.md)). -Open the ABP Studio UI and stop the application if it is already running. Then open the *Solution Explorer* in ABP Studio, right-click the `ModularCrm.Products` module and select the *Import Module* command: +Open the ABP Studio UI and stop the application if it is already running. Then open the *Solution Explorer* in ABP Studio, right-click the `ModularCrm.Catalog` module and select the *Import Module* command: ![abp-studio-import-module-ordering](images/abp-studio-import-module-ordering.png) @@ -150,11 +150,11 @@ In the opening dialog, find and select the `ModularCrm.Ordering` module, check t ![abp-studio-import-module-dialog-for-ordering](images/abp-studio-import-module-dialog-for-ordering.png) -Once you click the OK button, the Ordering module is imported to the Products module, and an installation dialog is open: +Once you click the OK button, the Ordering module is imported to the Catalog module, and an installation dialog is open: ![abp-studio-install-module-dialog-for-ordering](images/abp-studio-install-module-dialog-for-ordering.png) -Here, select the `ModularCrm.Ordering.Contracts` package on the left side (because we want to add that package reference) and `ModularCrm.Products.Domain` package on the middle area (because we want to add the package reference to that project). We installed it on the [domain layer](../../framework/architecture/domain-driven-design/domain-layer.md) of the Products module since we will create our event handler in that layer. Click the OK button to finish the installation operation. +Here, select the `ModularCrm.Ordering.Contracts` package on the left side (because we want to add that package reference) and `ModularCrm.Catalog` package on the middle area (because we want to add the package reference to that project). Also, select the `ModularCrm.Ordering` package on the right side, and unselect all packages on the middle area (we don't need the implementation or any other packages). Then, click the OK button to finish the installation operation. You can check the ABP Studio's *Solution Explorer* panel to see the module import and the project reference (dependency). @@ -162,15 +162,16 @@ You can check the ABP Studio's *Solution Explorer* panel to see the module impor ### Handling the `OrderPlacedEto` Event -Now, it is possible to use the `OrderPlacedEto` class inside the Product module's domain layer since it has the `ModularCrm.Ordering.Contracts` package reference. +Now, it is possible to use the `OrderPlacedEto` class inside the Catalog module since it has the `ModularCrm.Ordering.Contracts` package reference. -Open the Product module's .NET solution in your IDE, locate the `ModularCrm.Products.Domain` project, and create a new `Orders` folder and an `OrderEventHandler` class inside that folder. The final folder structure should be like this: +Open the Catalog module's .NET solution in your IDE, locate the `ModularCrm.Catalog` project, and create a new `Orders` folder and an `OrderEventHandler` class inside that folder. The final folder structure should be like this: ![visual-studio-order-event-handler](images/visual-studio-order-event-handler.png) Replace the `OrderEventHandler.cs` file's content with the following code block: ````csharp +using ModularCrm.Catalog; using ModularCrm.Ordering.Events; using System; using System.Threading.Tasks; @@ -178,34 +179,33 @@ using Volo.Abp.DependencyInjection; using Volo.Abp.Domain.Repositories; using Volo.Abp.EventBus.Distributed; -namespace ModularCrm.Products.Orders +namespace ModularCrm.Products.Orders; + +public class OrderEventHandler : + IDistributedEventHandler, + ITransientDependency { - public class OrderEventHandler : - IDistributedEventHandler, - ITransientDependency + private readonly IRepository _productRepository; + + public OrderEventHandler(IRepository productRepository) { - private readonly IRepository _productRepository; + _productRepository = productRepository; + } - public OrderEventHandler(IRepository productRepository) + public async Task HandleEventAsync(OrderPlacedEto eventData) + { + // Find the related product + var product = await _productRepository.FindAsync(eventData.ProductId); + if (product == null) { - _productRepository = productRepository; + return; } - public async Task HandleEventAsync(OrderPlacedEto eventData) - { - // Find the related product - var product = await _productRepository.FindAsync(eventData.ProductId); - if (product == null) - { - return; - } + // Decrease the stock count + product.StockCount = product.StockCount - 1; - // Decrease the stock count - product.StockCount = product.StockCount - 1; - - // Update the entity in the database - await _productRepository.UpdateAsync(product); - } + // Update the entity in the database + await _productRepository.UpdateAsync(product); } } ````