mirror of https://github.com/abpframework/abp
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
89 lines
6.6 KiB
89 lines
6.6 KiB
7 years ago
|
## Module Architecture Best Practices & Conventions
|
||
|
|
||
|
### Solution Structure
|
||
|
|
||
|
* **Do** create a separated Visual Studio solution for every module.
|
||
7 years ago
|
* **Do** name the solution as *CompanyName.ModuleName* (for core ABP modules, it's *Volo.Abp.ModuleName*).
|
||
|
* **Do** develop the module as layered, so it has several packages (projects) those are related to each other.
|
||
|
* Every package has its own module definition file and explicitly declares the dependencies for the depended packages/modules.
|
||
7 years ago
|
|
||
|
### Layers & Packages
|
||
|
|
||
|
The following diagram shows the packages of a well-layered module and dependencies of those packages between them:
|
||
|
|
||
|
![module-layers-and-packages](../images/module-layers-and-packages.jpg)
|
||
|
|
||
|
The ultimate goal is to allow an application to use the module in a flexible manner. Example applications:
|
||
|
|
||
7 years ago
|
* **A)** A **monolithic** application;
|
||
7 years ago
|
* Adds references to the **Web** and the **Application** packages.
|
||
7 years ago
|
* Adds a reference to one of the **EF Core** or the **MongoDB** packages based on the preference.
|
||
7 years ago
|
* The result;
|
||
|
* The application **can show UI** of the module.
|
||
|
* It hosts the **application** and **domain** layers in the **same process** (that's why it needs to have a reference to a database integration package).
|
||
|
* This application also **serves** the module's **HTTP API** (since it includes the HttpApi package through the Web package).
|
||
7 years ago
|
* **B)** An application that just serves the module as a **microservice**;
|
||
7 years ago
|
* Adds a reference to **HttpApi** and **Application** packages.
|
||
7 years ago
|
* Adds a reference to one of the **EF Core** or the **MongoDB** packages based on the preference.
|
||
7 years ago
|
* The result;
|
||
|
* The application **can not show UI** of the module since it does not have a reference to the Web package.
|
||
|
* It hosts the **application** and **domain** layers in the **same process** (that's why it needs to have a reference to a database integration package).
|
||
|
* This application **serves** the module's **HTTP API** (as the main goal of the application).
|
||
7 years ago
|
* **C)** An application that shows the module **UI** but does not host the application (just uses it as a remote service that is hosted by the application A or B);
|
||
7 years ago
|
* Adds a reference to the **Web** and the **HttpApi.Client** packages.
|
||
7 years ago
|
* Configures the remote endpoint for the HttpApi.Client package.
|
||
7 years ago
|
* The result;
|
||
|
* The application **can show UI** of the module.
|
||
|
* It does not host the application and domain layers of the module in the same process. Instead, uses it as a **remote service**.
|
||
|
* This application also **serves** the module's **HTTP API** (since it includes the HttpApi package through the Web package).
|
||
7 years ago
|
* **D)** A **client** application (or microservice) that just uses the module as a remote service (that is hosted by the application A, B or C);
|
||
7 years ago
|
* Adds a reference to the **HttpApi.Client** package.
|
||
7 years ago
|
* Configures the remote endpoint for the HttpApi.Client package.
|
||
7 years ago
|
* The result;
|
||
|
* The application can use all the functionality of the module as a **remote client**.
|
||
|
* The application is just a client and **can not serve** the **HTTP API** of the module.
|
||
|
* The application is just a client and **can not show** the **UI** of the module.
|
||
7 years ago
|
* **E**) A proxy application that hosts the HTTP API of the module but just forwards all requests to another application (that is hosted by the application A, B or C);
|
||
|
* Adds a reference to the **HttpApi** and **HttpApi.Client** packages.
|
||
|
* Configures the remote endpoint for the HttpApi.Client package.
|
||
|
* The result;
|
||
|
* The application can use all the functionality of the module as a **remote client**.
|
||
|
* This application also **serves** the module's **HTTP API**, but actually works just like a proxy by redirecting all requests (for the module) to another remote server.
|
||
7 years ago
|
|
||
|
Next section describes the packages in more details.
|
||
7 years ago
|
|
||
|
#### Domain Layer
|
||
|
|
||
|
* **Do** divide the domain layer into two projects:
|
||
7 years ago
|
* **Domain.Shared** package, named as *CompanyName.ModuleName.Domain.Shared*, that contains constants, enums and other types those can be safely shared with the all layers of the module. This package can also be shared to 3rd-party clients. It can not contain entities, repositories, domain services or any other business objects.
|
||
7 years ago
|
* **Domain** package, named as *CompanyName.ModuleName.Domain*, that contains entities, repository interfaces, domain service interfaces and their implementations and other domain objects.
|
||
7 years ago
|
* Domain package depends on the **Domain.Share** package.
|
||
7 years ago
|
|
||
|
#### Application Layer
|
||
|
|
||
|
* **Do** divide the application layer into two projects:
|
||
7 years ago
|
* **Application.Contracts** package, named as *CompanyName.ModuleName.Application.Contracts*, that contains application service interfaces and related data transfer objects.
|
||
|
* Application contract package depends on the **Domain.Shared** package.
|
||
7 years ago
|
* **Application** package, named as *CompanyName.ModuleName.Application*, that contains application service implementations.
|
||
7 years ago
|
* Application package depends on the **Domain** and the **Application.Contracts** packages.
|
||
7 years ago
|
|
||
|
#### Infrastructure Layer
|
||
|
|
||
|
* **Do** create a separated integration package for each ORM/database integration like Entity Framework Core and MongoDB.
|
||
7 years ago
|
* **Do**, for instance, create a *CompanyName.ModuleName.EntityFrameworkCore* package that abstracts the Entity Framework Core integration. ORM integration packages depend on the **Domain** package.
|
||
7 years ago
|
* **Do not** depend on other layers from the ORM/database integration package.
|
||
7 years ago
|
* **Do** create a separated integration package for each major library that is planned to be replaceable by another library without effecting the other packages.
|
||
7 years ago
|
|
||
|
#### HTTP Layer
|
||
|
|
||
|
* **Do** create an **HTTP API** package, named as *CompanyName.ModuleName.HttpApi*, to develop a REST style HTTP API for the module.
|
||
7 years ago
|
* HTTP API package only depends on the **Application.Contracts** package. It does not depend on the Application package.
|
||
|
* **Do** create a Controller for each application service (generally by implementing their interfaces). These controllers uses the application service interfaces to delegate the actions. It just configures routes, HTTP methods and other web related stuffs if needed.
|
||
7 years ago
|
* **Do** create an **HTTP API Client** package, named as *CompanyName.ModuleName.HttpApi.Client*, to provide client services for the HTTP API package. Those client services implement application interfaces as clients to a remote endpoint.
|
||
7 years ago
|
* HTTP API Client package only depends on the **Application.Contracts** package.
|
||
7 years ago
|
* **Do** use dynamic HTTP C# client proxy feature of the ABP framework.
|
||
|
|
||
|
#### Web Layer
|
||
|
|
||
|
* Do create a **Web** package, named as *CompanyName.ModuleName.Web*, that contains pages, views, scripts, styles, images and other UI components.
|
||
7 years ago
|
* Web package only depends on the **HttpApi** package.
|