diff --git a/docs/en/tutorials/modular-crm/images/abp-studio-add-entity-framework-core-migration.png b/docs/en/tutorials/modular-crm/images/abp-studio-add-entity-framework-core-migration.png index 857df5f25d..ee8b847a45 100644 Binary files a/docs/en/tutorials/modular-crm/images/abp-studio-add-entity-framework-core-migration.png and b/docs/en/tutorials/modular-crm/images/abp-studio-add-entity-framework-core-migration.png differ diff --git a/docs/en/tutorials/modular-crm/images/abp-studio-add-package-reference-5.png b/docs/en/tutorials/modular-crm/images/abp-studio-add-package-reference-5.png index 42d7c96cb2..cc3985bb75 100644 Binary files a/docs/en/tutorials/modular-crm/images/abp-studio-add-package-reference-5.png and b/docs/en/tutorials/modular-crm/images/abp-studio-add-package-reference-5.png differ diff --git a/docs/en/tutorials/modular-crm/images/abp-studio-browser-orders-menu-item.png b/docs/en/tutorials/modular-crm/images/abp-studio-browser-orders-menu-item.png index 3e4d83fee1..e552239474 100644 Binary files a/docs/en/tutorials/modular-crm/images/abp-studio-browser-orders-menu-item.png and b/docs/en/tutorials/modular-crm/images/abp-studio-browser-orders-menu-item.png differ diff --git a/docs/en/tutorials/modular-crm/images/abp-studio-build-and-restart-application.png b/docs/en/tutorials/modular-crm/images/abp-studio-build-and-restart-application.png index 889a4251cd..bf9c9d1ead 100644 Binary files a/docs/en/tutorials/modular-crm/images/abp-studio-build-and-restart-application.png and b/docs/en/tutorials/modular-crm/images/abp-studio-build-and-restart-application.png differ diff --git a/docs/en/tutorials/modular-crm/images/abp-studio-entity-framework-core-update-database.png b/docs/en/tutorials/modular-crm/images/abp-studio-entity-framework-core-update-database.png index b28b4e48a0..88a0a20bb3 100644 Binary files a/docs/en/tutorials/modular-crm/images/abp-studio-entity-framework-core-update-database.png and b/docs/en/tutorials/modular-crm/images/abp-studio-entity-framework-core-update-database.png differ diff --git a/docs/en/tutorials/modular-crm/images/abp-studio-import-module-for-ordering-dialog.png b/docs/en/tutorials/modular-crm/images/abp-studio-import-module-for-ordering-dialog.png index 762265b2c3..2b07060c2a 100644 Binary files a/docs/en/tutorials/modular-crm/images/abp-studio-import-module-for-ordering-dialog.png and b/docs/en/tutorials/modular-crm/images/abp-studio-import-module-for-ordering-dialog.png differ diff --git a/docs/en/tutorials/modular-crm/images/abp-studio-install-module-dialog.png b/docs/en/tutorials/modular-crm/images/abp-studio-install-module-dialog.png index 5ea22e8e3e..8c9abf1bf7 100644 Binary files a/docs/en/tutorials/modular-crm/images/abp-studio-install-module-dialog.png and b/docs/en/tutorials/modular-crm/images/abp-studio-install-module-dialog.png differ diff --git a/docs/en/tutorials/modular-crm/images/abp-studio-module-installation-dialog.png b/docs/en/tutorials/modular-crm/images/abp-studio-module-installation-dialog.png index 9946afaaec..eb71910650 100644 Binary files a/docs/en/tutorials/modular-crm/images/abp-studio-module-installation-dialog.png and b/docs/en/tutorials/modular-crm/images/abp-studio-module-installation-dialog.png differ diff --git a/docs/en/tutorials/modular-crm/images/abp-studio-open-with-visual-studio-main-app.png b/docs/en/tutorials/modular-crm/images/abp-studio-open-with-visual-studio-main-app.png index f4131cfb69..62a85d6589 100644 Binary files a/docs/en/tutorials/modular-crm/images/abp-studio-open-with-visual-studio-main-app.png and b/docs/en/tutorials/modular-crm/images/abp-studio-open-with-visual-studio-main-app.png differ diff --git a/docs/en/tutorials/modular-crm/images/abp-studio-ordering-swagger-ui-in-browser.png b/docs/en/tutorials/modular-crm/images/abp-studio-ordering-swagger-ui-in-browser.png index 304027af9e..1318691ae9 100644 Binary files a/docs/en/tutorials/modular-crm/images/abp-studio-ordering-swagger-ui-in-browser.png and b/docs/en/tutorials/modular-crm/images/abp-studio-ordering-swagger-ui-in-browser.png differ diff --git a/docs/en/tutorials/modular-crm/images/abp-studio-solution-runner-graph-build.png b/docs/en/tutorials/modular-crm/images/abp-studio-solution-runner-graph-build.png index 10d210a0be..d88c2b80c7 100644 Binary files a/docs/en/tutorials/modular-crm/images/abp-studio-solution-runner-graph-build.png and b/docs/en/tutorials/modular-crm/images/abp-studio-solution-runner-graph-build.png differ diff --git a/docs/en/tutorials/modular-crm/images/abp-studio-solution-runner-initial-product-page.png b/docs/en/tutorials/modular-crm/images/abp-studio-solution-runner-initial-product-page.png index 269c55f8b4..7f9b312b23 100644 Binary files a/docs/en/tutorials/modular-crm/images/abp-studio-solution-runner-initial-product-page.png and b/docs/en/tutorials/modular-crm/images/abp-studio-solution-runner-initial-product-page.png differ diff --git a/docs/en/tutorials/modular-crm/images/abp-studio-swagger-create-order.png b/docs/en/tutorials/modular-crm/images/abp-studio-swagger-create-order.png index e2c15fca23..01a2c5fe29 100644 Binary files a/docs/en/tutorials/modular-crm/images/abp-studio-swagger-create-order.png and b/docs/en/tutorials/modular-crm/images/abp-studio-swagger-create-order.png differ diff --git a/docs/en/tutorials/modular-crm/images/abp-studio-swagger-list-orders.png b/docs/en/tutorials/modular-crm/images/abp-studio-swagger-list-orders.png index e58ea0c51d..0fc7e63b23 100644 Binary files a/docs/en/tutorials/modular-crm/images/abp-studio-swagger-list-orders.png and b/docs/en/tutorials/modular-crm/images/abp-studio-swagger-list-orders.png differ diff --git a/docs/en/tutorials/modular-crm/images/abp-studio-swagger-ui-in-browser.png b/docs/en/tutorials/modular-crm/images/abp-studio-swagger-ui-in-browser.png index 8183cde1fb..1b5fec9205 100644 Binary files a/docs/en/tutorials/modular-crm/images/abp-studio-swagger-ui-in-browser.png and b/docs/en/tutorials/modular-crm/images/abp-studio-swagger-ui-in-browser.png differ diff --git a/docs/en/tutorials/modular-crm/images/solution-explorer-modular-crm-expanded.png b/docs/en/tutorials/modular-crm/images/solution-explorer-modular-crm-expanded.png index 841b8fe610..3156b75fb1 100644 Binary files a/docs/en/tutorials/modular-crm/images/solution-explorer-modular-crm-expanded.png and b/docs/en/tutorials/modular-crm/images/solution-explorer-modular-crm-expanded.png differ diff --git a/docs/en/tutorials/modular-crm/images/visual-studio-main-dbcontext.png b/docs/en/tutorials/modular-crm/images/visual-studio-main-dbcontext.png index 825b6c2422..0a2db8ed76 100644 Binary files a/docs/en/tutorials/modular-crm/images/visual-studio-main-dbcontext.png and b/docs/en/tutorials/modular-crm/images/visual-studio-main-dbcontext.png differ diff --git a/docs/en/tutorials/modular-crm/images/visual-studio-new-migration-class-2.png b/docs/en/tutorials/modular-crm/images/visual-studio-new-migration-class-2.png index 3acc6e45c7..c5a698db58 100644 Binary files a/docs/en/tutorials/modular-crm/images/visual-studio-new-migration-class-2.png and b/docs/en/tutorials/modular-crm/images/visual-studio-new-migration-class-2.png differ diff --git a/docs/en/tutorials/modular-crm/images/visual-studio-new-migration-class.png b/docs/en/tutorials/modular-crm/images/visual-studio-new-migration-class.png index b18d071cb1..24c7cb3299 100644 Binary files a/docs/en/tutorials/modular-crm/images/visual-studio-new-migration-class.png and b/docs/en/tutorials/modular-crm/images/visual-studio-new-migration-class.png differ diff --git a/docs/en/tutorials/modular-crm/images/visual-studio-order-reporting-app-service-impl.png b/docs/en/tutorials/modular-crm/images/visual-studio-order-reporting-app-service-impl.png deleted file mode 100644 index 5007486775..0000000000 Binary files a/docs/en/tutorials/modular-crm/images/visual-studio-order-reporting-app-service-impl.png and /dev/null differ diff --git a/docs/en/tutorials/modular-crm/images/visual-studio-order-reporting-app-service.png b/docs/en/tutorials/modular-crm/images/visual-studio-order-reporting-app-service.png index 7333958f11..1dcead7f0d 100644 Binary files a/docs/en/tutorials/modular-crm/images/visual-studio-order-reporting-app-service.png and b/docs/en/tutorials/modular-crm/images/visual-studio-order-reporting-app-service.png differ diff --git a/docs/en/tutorials/modular-crm/images/visual-studio-ordering-contracts.png b/docs/en/tutorials/modular-crm/images/visual-studio-ordering-contracts.png index d9206f6630..512edaa4a1 100644 Binary files a/docs/en/tutorials/modular-crm/images/visual-studio-ordering-contracts.png and b/docs/en/tutorials/modular-crm/images/visual-studio-ordering-contracts.png differ diff --git a/docs/en/tutorials/modular-crm/part-01.md b/docs/en/tutorials/modular-crm/part-01.md index 316aff6150..ddc6e8debe 100644 --- a/docs/en/tutorials/modular-crm/part-01.md +++ b/docs/en/tutorials/modular-crm/part-01.md @@ -3,6 +3,10 @@ ````json //[doc-nav] { + "Previous": { + "Name": "Overview", + "Path": "tutorials/modular-crm/index" + }, "Next": { "Name": "Creating the initial Products module", "Path": "tutorials/modular-crm/part-02" @@ -10,7 +14,7 @@ } ```` -Follow the *[Get Started](../../get-started/layered-web-application.md)* guide to create a new layered web application with the following configuration: +Follow the *[Get Started](../../get-started/single-layer-web-application.md)* guide to create a single layer web application with the following configuration: * **Solution name**: `ModularCrm` * **UI Framework**: ASP.NET Core MVC / Razor Pages @@ -18,7 +22,7 @@ Follow the *[Get Started](../../get-started/layered-web-application.md)* guide t You can select the other options based on your preference. -> **Please complete the [Get Stared](../../get-started/layered-web-application.md) guide and run the web application before going further.** +> **Please complete the [Get Started](../../get-started/single-layer-web-application.md) guide and run the web application before going further.** The initial solution structure should be like the following in ABP Studio's *[Solution Explorer](../../studio/solution-explorer.md)*: @@ -28,10 +32,10 @@ Initially, you see a `ModularCrm` solution and a `ModularCrm` module under that > An ABP Studio module is typically a .NET solution and an ABP Studio solution is an umbrella concept for multiple .NET Solutions (see the [concepts](../../studio/concepts.md) document for more). -`ModularCrm` module is your main application, which is a layered .NET solution that consists of several packages (.NET projects). You can expand the `ModularCrm` module to see its packages: +The `ModularCrm` module is the core of your application, built as a single-layer ASP.NET Core Web application. You can expand the `ModularCrm` module to see: ![solution-explorer-modular-crm-expanded](images/solution-explorer-modular-crm-expanded.png) ## Summary -We've created the initial layered monolith solution. In the next part, we will learn how to create a new application module and install it to the main application. +We've created the initial single layer monolith solution. In the next part, we will learn how to create a new application module and install it to the main application. diff --git a/docs/en/tutorials/modular-crm/part-02.md b/docs/en/tutorials/modular-crm/part-02.md index 8a5b4b9e6c..034b4b7bfe 100644 --- a/docs/en/tutorials/modular-crm/part-02.md +++ b/docs/en/tutorials/modular-crm/part-02.md @@ -32,12 +32,13 @@ Create a `main` and a `modules` folder using the *New Folder* command, then move ## Creating The Module -There are two module templates provided by ABP Studio: +There are three module templates provided by ABP Studio: * **Empty Module**: You can use that module template to build your module structure from scratch. * **DDD Module**: A Domain Driven Design based layered module structure. +* **Standard Module**: A module template that is similar to the DDD module but without the domain layer. -We will use the *DDD Module* template for the Product module and the *Empty Module* template later in this tutorial. +We will use the *DDD Module* template for the Product module and the *Standard Module* template later in this tutorial. Right-click the `modules` folder on the *Solution Explorer* panel, and select the *Add* -> *New Module* -> *DDD Module* command: @@ -115,7 +116,7 @@ When you click the *OK* button, ABP Studio opens the *Install Module* dialog: ![abp-studio-module-installation-dialog](images/abp-studio-module-installation-dialog.png) -This dialog simplifies installing a multi-layer module to a multi-layer application. It automatically determines which package of the `ModularCrm.Products` module should be installed to which package of the main application. For example, the `ModularCrm.Products.Domain` package is installed to the `ModularCrm.Domain` package. In that way, you can use domain objects ([entities](../../framework/architecture/domain-driven-design/entities.md), [repositories](../../framework/architecture/domain-driven-design/repositories.md), ...) of the products module from the domain layer of your main application. +This dialog simplifies installing a multi-layer module to a single-layer application. It automatically determines which package of the `ModularCrm.Products` module should be installed to which package of the main application. The default package match is good for this tutorial, so you can click the *OK* button to proceed. @@ -131,7 +132,7 @@ Graph Build is a dotnet CLI command that recursively builds all the referenced d ### Run the Main Application -Open the *Solution Runner* panel, click the *Play* button (near to the solution root), right-click the `ModularCrm.Web` application and select the *Browse* command. It will open the web application in the built-in browser. Then you can navigate to the *Products* page on the main menu of the application to see the Products page that is coming from the `ModularCrm.Products` module: +Open the *Solution Runner* panel, click the *Play* button (near to the solution root), right-click the `ModularCrm` application and select the *Browse* command. It will open the web application in the built-in browser. Then you can navigate to the *Products* page on the main menu of the application to see the Products page that is coming from the `ModularCrm.Products` module: ![abp-studio-solution-runner-initial-product-page](images/abp-studio-solution-runner-initial-product-page.png) diff --git a/docs/en/tutorials/modular-crm/part-03.md b/docs/en/tutorials/modular-crm/part-03.md index 799745b9c8..3d8896d8a5 100644 --- a/docs/en/tutorials/modular-crm/part-03.md +++ b/docs/en/tutorials/modular-crm/part-03.md @@ -164,7 +164,7 @@ Open the `ModularCrm` module (which is the main application) in your IDE: ![abp-studio-open-with-visual-studio-main-app](images/abp-studio-open-with-visual-studio-main-app.png) -Find the `ModularCrmDbContext` class under the `ModularCrm.EntityFrameworkCore` project: +Open the `ModularCrmDbContext` class under the `ModularCrm` project's `Data` folder: ![visual-studio-main-dbcontext](images/visual-studio-main-dbcontext.png) @@ -185,10 +185,9 @@ Follow the three steps below; **(2)** Implement the `IProductsDbContext` by the `ModularCrmDbContext` class: ````csharp +[ReplaceDbContext(typeof(IProductsDbContext))] public class ModularCrmDbContext : AbpDbContext, - ITenantManagementDbContext, - IIdentityDbContext, IProductsDbContext //NEW: IMPLEMENT THE INTERFACE { public DbSet Products { get; set; } //NEW: ADD DBSET PROPERTY @@ -214,7 +213,7 @@ Now, we can add a new database migration. You can use Entity Framework Core's `A Ensure that the solution has built. You can right-click the `ModularCrm` (under the `main` folder) on ABP Studio *Solution Runner* and select the *Dotnet CLI* -> *Graph Build* command. -Right-click the `ModularCrm.EntityFrameworkCore` package and select the *EF Core CLI* -> *Add Migration* command: +Right-click the `ModularCrm` package and select the *EF Core CLI* -> *Add Migration* command: ![abp-studio-add-entity-framework-core-migration](images/abp-studio-add-entity-framework-core-migration.png) @@ -222,7 +221,7 @@ The *Add Migration* command opens a new dialog to get a migration name: ![abp-studio-add-entity-framework-core-migration-dialog](images/abp-studio-add-entity-framework-core-migration-dialog.png) -Once you click the *OK* button, a new database migration class is added to the `Migrations` folder of the `ModularCrm.EntityFrameworkCore` project: +Once you click the *OK* button, a new database migration class is added to the `Migrations` folder of the `ModularCrm` project: ![visual-studio-new-migration-class](images/visual-studio-new-migration-class.png) @@ -369,7 +368,7 @@ For this application, we don't need to create HTTP API endpoints for the product * You can create a regular ASP.NET Core Controller class in the `ModularCrm.Products.HttpApi` project, inject `IProductAppService` and use it to create wrapper methods. We will do this later while we create the Ordering module. * Alternatively, you can use the ABP's [Auto API Controllers](../../framework/api-development/auto-controllers.md) feature to expose your application services as API controllers by conventions. We will do it here. -Open the `ModularCrmWebModule` class in the main application's solution (the `ModularCrm` solution), find the `PreConfigureServices` method and add the following lines inside that method: +Open the `ModularCrmModule` class in the main application's solution (the `ModularCrm` solution), find the `PreConfigureServices` method and add the following lines inside that method: ````csharp PreConfigure(mvcBuilder => @@ -385,8 +384,8 @@ Then open the `ConfigureAutoApiControllers` method of the same class and add a s ````csharp Configure(options => { - options.ConventionalControllers.Create(typeof(ModularCrmApplicationModule).Assembly); - + options.ConventionalControllers.Create(typeof(ModularCrmModule).Assembly); + //ADD THE FOLLOWING LINE: options.ConventionalControllers.Create(typeof(ProductsApplicationModule).Assembly); }); @@ -404,7 +403,7 @@ This section will create a few example products using the [Swagger UI](../../fra Now, right-click the `ModularCrm` under the `main` folder in the Solution Explorer panel and select the *Dotnet CLI* -> *Graph Build* command. This will ensure that the product module and the main application are built and ready to run. -After the build process completes, open the Solution Runner panel and click the *Play* button near the solution root. Once the `ModularCrm.Web` application runs, we can right-click it and select the *Browse* command to open the user interface. +After the build process completes, open the Solution Runner panel and click the *Play* button near the solution root. Once the `ModularCrm` application runs, we can right-click it and select the *Browse* command to open the user interface. Once you see the user interface of the web application, type `/swagger` at the end of the URL to open the Swagger UI. If you scroll down, you should see the `Products` API: @@ -486,7 +485,7 @@ Here, we simply use the `IProductAppService` to get a list of all products and a ```` -You can build the product module's .NET solution (`ModularCrm.Products`), then right-click the `ModularCrm.Web` application on ABP Studio's solution runner and select the *Build & Restart* command: +Right-click the `ModularCrm` application on ABP Studio's solution runner and select the *Start* command: ![abp-studio-build-and-restart-application](images/abp-studio-build-and-restart-application.png) diff --git a/docs/en/tutorials/modular-crm/part-04.md b/docs/en/tutorials/modular-crm/part-04.md index 1674ced6c6..ba406f7846 100644 --- a/docs/en/tutorials/modular-crm/part-04.md +++ b/docs/en/tutorials/modular-crm/part-04.md @@ -70,8 +70,6 @@ Select the `ModularCrm.Ordering` module and check the *Install this module* opti ![abp-studio-install-module-dialog](images/abp-studio-install-module-dialog.png) -Select the `ModuleCrm.Ordering` package from the left area and the `ModularCrm.Domain` package from the middle area. Then, select the `ModularCrm.Ordering.UI` package from the left area and the `ModularCrm.Web` package from the middle area, as shown in the preceding figure. Finally, click *OK*. - -> Since the Ordering module is not layered, we didn't install its packages to the layers of our main application. We are installing it only to `ModularCrm.Domain`. In this way, we can use the Ordering module from any layer of our application since `ModularCrm.Domain` is one of the core packages of our application. If you build your modules as non-layered and you don't have much code in the main application's .NET solution, you can also consider creating a non-layered main application that composes these modules. +Select the `ModuleCrm.Ordering` and `ModularCrm.Ordering.UI` packages from the left area and the `ModularCrm` package from the middle area as shown in the preceding figure. Finally, click *OK*. In this part of the tutorial, we've created a standard module. This allows you to create modules or applications with a different structure. In the next part, we will add functionality to the Ordering module. diff --git a/docs/en/tutorials/modular-crm/part-05.md b/docs/en/tutorials/modular-crm/part-05.md index c5279b405a..a489548b65 100644 --- a/docs/en/tutorials/modular-crm/part-05.md +++ b/docs/en/tutorials/modular-crm/part-05.md @@ -28,7 +28,7 @@ Create an `Order` class to the `ModularCrm.Ordering` project (open an `Entities` ````csharp using System; -using ModularCrm.Ordering.Contracts.Enums; +using ModularCrm.Ordering.Enums; using Volo.Abp.Domain.Entities.Auditing; namespace ModularCrm.Ordering.Entities @@ -156,7 +156,7 @@ public static class OrderingDbContextModelCreatingExtensions #### Configuring the Main Application -Open the main application's solution in your IDE, find the `ModularCrmDbContext` class under the `ModularCrm.EntityFrameworkCore` project and follow the 3 steps below: +Open the main application's solution in your IDE, find the `ModularCrmDbContext` class under the `ModularCrm` project's `Data` folder, and follow the 3 steps below: **(1)** Add the following attribute on top of the `ModularCrmDbContext` class: @@ -171,8 +171,6 @@ The `ReplaceDbContext` attribute allows the use of the `ModularCrmDbContext` cla ````csharp public class ModularCrmDbContext : AbpDbContext, - ITenantManagementDbContext, - IIdentityDbContext, IProductsDbContext, IOrderingDbContext //NEW: IMPLEMENT THE INTERFACE { @@ -200,7 +198,7 @@ Now, we can add a new database migration. You can use Entity Framework Core's `A Ensure that the solution has built. You can right-click the `ModularCrm` (under the `main` folder) on ABP Studio *Solution Runner* and select the *Dotnet CLI* -> *Graph Build* command. -Right-click the `ModularCrm.EntityFrameworkCore` package and select the *EF Core CLI* -> *Add Migration* command: +Right-click the `ModularCrm` package and select the *EF Core CLI* -> *Add Migration* command: ![abp-studio-add-entity-framework-core-migration](images/abp-studio-add-entity-framework-core-migration.png) @@ -208,11 +206,11 @@ The *Add Migration* command opens a new dialog to get a migration name: ![abp-studio-entity-framework-core-add-migration-order](images/abp-studio-entity-framework-core-add-migration-order.png) -Once you click the *OK* button, a new database migration class is added to the `Migrations` folder of the `ModularCrm.EntityFrameworkCore` project: +Once you click the *OK* button, a new database migration class is added to the `Migrations` folder of the `ModularCrm` project: ![visual-studio-new-migration-class-2](images/visual-studio-new-migration-class-2.png) -Now, you can return to ABP Studio, right-click the `ModularCrm.EntityFrameworkCore` project and select the *EF Core CLI* -> *Update Database* command: +Now, you can return to ABP Studio, right-click the `ModularCrm` project and select the *EF Core CLI* -> *Update Database* command: ![abp-studio-entity-framework-core-update-database](images/abp-studio-entity-framework-core-update-database.png) @@ -347,14 +345,14 @@ public class OrderAppService : OrderingAppService, IOrderAppService } ```` -Open the `ModularCrmWebModule` class in the main application's solution (the `ModularCrm` solution), find the `ConfigureAutoApiControllers` method and add the following lines inside that method: +Open the `ModularCrmModule` class in the main application's solution (the `ModularCrm` solution), find the `ConfigureAutoApiControllers` method and add the following lines inside that method: ````csharp private void ConfigureAutoApiControllers() { Configure(options => { - options.ConventionalControllers.Create(typeof(ModularCrmApplicationModule).Assembly); + options.ConventionalControllers.Create(typeof(ModularCrmModule).Assembly); options.ConventionalControllers.Create(typeof(ProductsApplicationModule).Assembly); //ADD THE FOLLOWING LINE: @@ -369,7 +367,7 @@ This section will create a few example orders using the [Swagger UI](../../frame Now, right-click the `ModularCrm` under the `main` folder in the Solution Explorer panel and select the *Dotnet CLI* -> *Graph Build* command. This will ensure that the order module and the main application are built and ready to run. -After the build process completes, open the Solution Runner panel and click the *Play* button near the solution root. Once the `ModularCrm.Web` application runs, we can right-click it and select the *Browse* command to open the user interface. +After the build process completes, open the Solution Runner panel and click the *Play* button near the solution root. Once the `ModularCrm` application runs, we can right-click it and select the *Browse* command to open the user interface. Once you see the user interface of the web application, type `/swagger` at the end of the URL to open the Swagger UI. If you scroll down, you should see the `Orders` API: @@ -487,11 +485,11 @@ public class OrderingMenuContributor : IMenuContributor ### Building the Application -Now, we will run the application to see the result. Please stop the application if it is already running. Then open the *Solution Runner* panel, right-click the `ModularCrm.Web` application, and select the *Build* -> *Graph Build* command: +Now, we will run the application to see the result. Please stop the application if it is already running. Then open the *Solution Runner* panel, right-click the `ModularCrm` application, and select the *Build* -> *Graph Build* command: ![abp-studio-solution-runner-graph-build](images/abp-studio-solution-runner-graph-build.png) -We've performed a graph build since we've made a change on a module, and more than building the main application is needed. *Graph Build* command also builds the depended modules if necessary. Alternatively, you could build the Ordering module first (on ABP Studio or your IDE). This approach can be faster if you have too many modules and you make a change in one of the modules. Now you can run the application by right-clicking the `ModularCrm.Web` application and selecting the *Start* command. +We've performed a graph build since we've made a change on a module, and more than building the main application is needed. *Graph Build* command also builds the depended modules if necessary. Alternatively, you could build the Ordering module first (on ABP Studio or your IDE). This approach can be faster if you have too many modules and you make a change in one of the modules. Now you can run the application by right-clicking the `ModularCrm` application and selecting the *Start* command. ![abp-studio-browser-orders-menu-item](images/abp-studio-browser-orders-menu-item.png) diff --git a/docs/en/tutorials/modular-crm/part-07.md b/docs/en/tutorials/modular-crm/part-07.md index 4d0553daaa..4bcace4239 100644 --- a/docs/en/tutorials/modular-crm/part-07.md +++ b/docs/en/tutorials/modular-crm/part-07.md @@ -19,7 +19,7 @@ Another common approach to communicating between modules is messaging. By publis ABP provides two types of event buses for loosely coupled communication: * [Local Event Bus](../../framework/infrastructure/event-bus/local/index.md) is suitable for in-process messaging. Since in a modular monolith, both of publisher and subscriber are in the same process, they can communicate in-process, without needing an external message broker. -* **[Distributed Event Bus](../../framework/infrastructure/event-bus/distributed/index.md)** is normal for inter-process messaging, like microservices, for publishing and subscribing to distributed events. However, ABP's distributed event bus works as local (in-process) by default (actually, it uses the Local Event Bus under the hood by default) unless you configure an external message broker. +* [Distributed Event Bus](../../framework/infrastructure/event-bus/distributed/index.md) is normal for inter-process messaging, like microservices, for publishing and subscribing to distributed events. However, ABP's distributed event bus works as local (in-process) by default (actually, it uses the Local Event Bus under the hood by default) unless you configure an external message broker. If you consider converting your modular monolith to a microservice system later, it is best to use the Distributed Event Bus with default local/in-process implementation. It already supports database-level transactional event execution and has no performance penalty. If you switch to an external provider ([RabbitMQ](../../framework/infrastructure/event-bus/distributed/rabbitmq.md), [Kafka](../../framework/infrastructure/event-bus/distributed/kafka.md), etc.), you don't need to change your application code. @@ -184,9 +184,9 @@ namespace ModularCrm.Products.Orders IDistributedEventHandler, ITransientDependency { - private readonly IProductRepository _productRepository; + private readonly IRepository _productRepository; - public OrderEventHandler(IProductRepository productRepository) + public OrderEventHandler(IRepository productRepository) { _productRepository = productRepository; } @@ -218,7 +218,7 @@ We inject the product repository and update the stock count in the event handler To keep this tutorial more focused, we will not create a UI for creating an order. You can easily create a form to create an order on your user interface. In this section, we will test it just using the Swagger UI. -Graph build the `ModularCrm.Web` application, run it on the ABP Studio's *Solution Runner* panel and browse the application UI as demonstrated earlier. +Graph build the `ModularCrm` application, run it on the ABP Studio's *Solution Runner* panel and browse the application UI as demonstrated earlier. Once the application is running and ready, manually type `/swagger` to the end of the URL and press the ENTER key. You should see the Swagger UI that is used to discover and test your HTTP APIs: @@ -228,8 +228,8 @@ Find the *Orders* API, click the *Try it out* button, enter a sample value the t ````json { - "productId": "0fbf7dd0-d7e9-0d18-9214-3a14d9fa1b74", - "customerName": "David" + "customerName": "David", + "productId": "e6ce1629-cfb1-1af6-e71c-3a16f10f9cc5" } ```` diff --git a/docs/en/tutorials/modular-crm/part-08.md b/docs/en/tutorials/modular-crm/part-08.md index 20efa3d7bd..6291875d5c 100644 --- a/docs/en/tutorials/modular-crm/part-08.md +++ b/docs/en/tutorials/modular-crm/part-08.md @@ -43,7 +43,7 @@ We will define the `IOrderReportingAppService` interface in the `ModularCrm.Appl As the first step, we should reference the `ModularCrm.Ordering.Contracts` package (of the `ModularCrm.Ordering` module) since we will reuse the `OrderState` enum defined in that package. -Open the ABP Studio's *Solution Explorer* panel, right-click the `ModularCrm.Application.Contracts` package and select the *Add Package Reference* command: +Open the ABP Studio's *Solution Explorer* panel, right-click the `ModularCrm` package and select the *Add Package Reference* command: ![abp-studio-add-package-reference-5](images/abp-studio-add-package-reference-5.png) @@ -55,7 +55,7 @@ The package reference has been added, and we can now use the types in the `Modul #### Defining the `IOrderReportingAppService` Interface -Open the main `ModularCrm` .NET solution in your IDE, find the `ModularCrm.Application.Contracts` project, create an `Orders` folder and add an `IOrderReportingAppService` interface. Here is the definition of that interface: +Open the main `ModularCrm` .NET solution in your IDE, create an `Orders` folder under the `Services` folder and add an `IOrderReportingAppService` interface. Here is the definition of that interface: ````csharp using System.Collections.Generic; @@ -71,7 +71,7 @@ namespace ModularCrm.Orders } ```` -We have a single method, `GetLatestOrders`, that will return a list of the latest orders. We should also define the `OrderReportDto` class that that method returns. Create the following class in the same `Orders` folder: +We have a single method, `GetLatestOrders`, that will return a list of the latest orders. We should also define the `OrderReportDto` class that that method returns. Create the `Orders` folder under the `Services/Dtos` folder and create a class named `OrderReportDto`. ````csharp using System; @@ -93,7 +93,7 @@ namespace ModularCrm.Orders } ```` -`OrderReportDto` contains data from both the `Order` and `Product` entities. We could use the `OrderState` since we have a reference to the package that defines that enum. +`OrderReportDto` contains data from both the `Order` and `Product` entities. We could use the `OrderState` since we have a reference to the package that defines that enum. After adding these files, the final folder structure should be like this: @@ -101,9 +101,7 @@ After adding these files, the final folder structure should be like this: ### Implementing the `OrderReportingAppService` Class -Create an `Orders` folder inside the `ModularCrm.Application` project and add a class named `OrderReportingAppService` inside it. The final folder structure should be like this: - -![visual-studio-order-reporting-app-service-impl](images/visual-studio-order-reporting-app-service-impl.png) +Create a class named `OrderReportingAppService` under the `Services/Orders` folder. Open the `OrderReportingAppService.cs` file and change its content by the following code block: @@ -176,7 +174,7 @@ Open the ABP Studio UI, stop the application if it is running, build and run it Here, find the `OrderReporting` API and execute it as shown above. You should get the order objects with product names. -Alternatively, you can visit the `/api/app/order-reporting/latest-orders` URL to directly execute the HTTP API on the browser (you should write the full URL, like `https://localhost:44358/api/app/order-reporting/latest-orders` - port can be different for your case) +Alternatively, you can visit the `/api/app/order-reporting/latest-orders` URL to directly execute the HTTP API on the browser (you should write the full URL, like `https://localhost:44303/api/app/order-reporting/latest-orders` - port can be different for your case) ## Summary @@ -190,7 +188,7 @@ Now, you know the fundamental principles and mechanics of building sophisticated ## Download the Source Code -You can download the completed sample solution [here](https://github.com/abpframework/abp-samples/tree/master/ModularCRM). +You can download the completed sample solution [here](https://github.com/abpframework/abp-samples/tree/master/ModularCrm). ## See Also