嘗試從零開始構建我的商城 (一) :使用Abp vNext快速一個簡單的商城專案
阿新 • • 發佈:2020-10-22
# 嘗試從零開始構建我的商城 (一) :使用Abp vNext快速搭建一個簡單的專案
## 前言
### GitHub地址
> https://github.com/yingpanwang/MyShop
### 此文目的
本文將嘗試使用Abp vNext 搭建一個商城系統並儘可能從業務,架構相關方向優化升級專案結構,並會將每次升級所涉及的模組及特性以blog的方式展示出來。
## 程式碼實踐
> Abp vNext 使用 DDD 領域驅動設計 是非常方便的,但是由於本人認為自身沒有足夠的功力玩轉DDD,所以開發中使用的是基於貧血模型的設計的開發,而不是遵照DDD的方式
### Domain 領域層
#### 1.新增引用
> 通過 **Nuget** 安裝 **Volo.Abp.Ddd.Domain**
#### 2.定義模組
建立 **MyShopDomainModule.cs** 作為Domain的模組,Domain不依賴任何外部模組,本體也沒有什麼相關配置,所以只需要繼承AbpModule即可
``` csharp
namespace MyShop.Domain
{
public class MyShopDomainModule:AbpModule
{
}
}
```
#### 3.定義實體
###### BaseEntity 實體基類
定義BaseEntity並繼承由**Volo.Abp.Ddd.Domain**提供的Entity並新增**CreationTime**屬性
``` csharp
public class BaseEntity :Entity
{
public DateTime CreationTime { get; set; } = DateTime.Now;
}
```
###### Product 商品
繼承**BaseEntity**類 新增相關屬性
``` csharp
///
/// 商品資訊
///
public class Product :BaseEntity
{
///
/// 名稱
///
public string Name { get; set; }
///
/// 分類id
///
public long CategoryId { get; set; }
///
/// 價格
///
public decimal? Price { get; set; }
///
/// 描述
///
public string Description { get; set; }
///
/// 庫存
///
public decimal Stock { get; set; }
}
```
###### Order 訂單
繼承**BaseEntity**類 新增相關屬性
``` csharp
///
/// 訂單
///
public class Order:BaseEntity
{
///
/// 訂單號
///
public Guid OrderNo { get; set; } = Guid.NewGuid();
///
/// 使用者
///
public long UserId { get; set; }
///
/// 訂單狀態
///
public OrderStatus OrderStatus { get; set; }
///
/// 總金額
///
public decimal Total { get; set; }
///
/// 地址
///
public string Address { get; set; }
}
public enum OrderStatus
{
Created,
Cancel,
Paid,
}
```
### Application 應用層實現
#### 1.新增引用
> 通過 **Nuget** 安裝 **Volo.Abp.Application**
> 通過 **Nuget** 安裝 **Volo.Abp.AutoMapper**
#### 2.定義模組
建立 **MyShopApplicationModule.cs** ,繼承自AbpModule,並且依賴Domain以及ApplicationContract層和後續使用的AutoMapper,所以對應DependsOn中需要新增對應依賴
``` csharp
///
/// 專案模組依賴
///
[DependsOn(typeof(MyShopApplicationContractModule),
typeof(MyShopDomainModule))]
/// 元件依賴
[DependsOn(typeof(AbpAutoMapperModule))]
public class MyShopApplicationModule:AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
//新增ObjectMapper注入
context.Services.AddAutoMapperObjectMapper();
// Abp AutoMapper設定
Configure(config =>
{
// 新增對應依賴關係Profile
config.AddMaps();
});
}
}
```
#### 3.實現相關服務
這裡由於我們使用AutoMapper所以需要建立Profile並新增相關對映關係
##### Profile定義
``` csharp
namespace MyShop.Application.AutoMapper.Profiles
{
public class MyShopApplicationProfile:Profile
{
public MyShopApplicationProfile()
{
CreateMap().ReverseMap();
CreateMap().ReverseMap();
}
}
}
```
##### 服務實現
Abp 可以很方便的將我們的服務向外暴露,通過簡單配置可以自動生成對應介面,只需要需要暴露的服務
繼承ApplicationService。
> **Abp**在確定服務方法的**HTTP Method**時使用命名約定:
**Get**: 如果方法名稱以**GetList**,**GetAll**或**Get**開頭.
**Put**: 如果方法名稱以**Put**或**Update**開頭.
**Delete**: 如果方法名稱以**Delete**或**Remove**開頭.
**Post**: 如果方法名稱以**Create**,**Add**,**Insert**或**Post**開頭.
**Patch**: 如果方法名稱以**Patch**開頭.
**其他情況**, **Post** 為 預設方式.
###### OrderApplicationService
``` csharp
public class OrderApplicationService : ApplicationService, IOrderApplicationService
{
private readonly IRepository _orderRepository;
public OrderApplicationService(IRepository orderRepository)
{
_orderRepository = orderRepository;
}
public async Task GetAsync(long id)
{
var order = await _orderRepository.GetAsync(g => g.Id == id);
return ObjectMapper.Map(order);
}
public async Task
- > GetListAsync()
{
var orders = await _orderRepository.GetListAsync();
return ObjectMapper.Map
- , List
- > GetListAsync()
{
var products = await _productRepository.GetListAsync();
return ObjectMapper.Map
- , List
- > GetListAsync();
}
```
###### IProductApplicationService
``` csharp
public interface IProductApplicationService :IApplicationService
{
Task
- > GetListAsync();
IPagedResult