ABP官方文件翻譯 3 4 領域服務

2021-08-01 07:54:05 字數 3117 閱讀 7135

領域服務

一些**

介紹

領域服務(或者在ddd中單純的服務)用來執行領域操作和業務規則。eric evans在他的ddd書中描述了乙個好的服務有三個特徵:

1. 與領域概念關聯的操作,但不是實體或值物件的自然組成部分。

2. 介面的定義依照領域模型的其他元素。

3. 操作是無狀態的。

不像應用服務那樣獲取或返回dto,領域服務獲取或返回領域物件(如實體或值物件)。

領域服務可以被應用服務或其他領域服務使用,但不能被展現層(應用層可以)直接使用。

idomainservice介面和domainservice類

abp定義了idomainservice介面,並約定所有的領域服務都實現這個介面。當被實現時,領域服務自動註冊到依賴注入系統,呼叫型別為臨時的。

領域服務可以繼承domainservice類。從而,可以使用一些繼承屬性來記錄日誌,本地化等等。當然,即使沒有繼承,如果需要的話也可以注入他們。

示例

假定我們有乙個任務管理系統,當分配任務到乙個人的時候需要執行業務規則。

建立介面

首先,我們定義這個服務的介面(不是必須,但最好這樣作為最佳實踐):

public

inte***ce itaskmanager : idomainservice

如上所見,taskmanager服務使用領域物件工作:taskperson。命名領域服務有些約定,可以為taskmanager、taskservice或taskdomainservice.....

服務實現

讓我們來看看如何實現:

public

class taskmanager : domainservice, itaskmanager

public

void assigntasktoperson(task task, person person)

if (task.state != taskstate.active)

if (haspersonmaximumassignedtask(person))

task.assignedpersonid = person.id;

}private

bool haspersonmaximumassignedtask(person person)

}

這裡,我們有兩條業務規則:

現在,我們看看如何從應用服務中使用taskmanager:

public

public

void assigntasktoperson(assigntasktopersoninput input)

}

任務應用服務使用指定的dto(input)和倉儲獲取相關的任務和人,並把他們傳遞給task manager(領域服務)。

一些**

基於上面的示例,你可能有些問題。

你可能會說為什麼應用服務不實現在領域服務的邏輯?

我們可以簡單來說,這不是應用服務的任務。因為這不是乙個用例而是業務操作。我們或許會使用同樣的「分配乙個任務到人」的領域邏輯在不同的用例下。比方說,我們可能有另乙個場景,某種情況下更新了這個任務並且這個更新包含分配這個任務到另乙個人。所以,我們可以在這裡使用相同的領域邏輯。還有,我們可能有兩個不同的ui(乙個移動應用和乙個web應用)共享相同的領域或者我們可能有有乙個為遠端客戶端使用的web api,而遠端客戶端包含分配任務的操作。

如果你的領域比較簡單,只有乙個ui並且分配任務到人只在乙個點完成,那麼可以考慮跳過領域服務,直接在應用服務實現邏輯。這對ddd來講不是最佳實踐,但是abp並不強制。

如何強制使用領域服務?

可以看到,應用服務可以很容易的使用領域服務

public

void assigntasktoperson(assigntasktopersoninput input)

寫領域服務的開發者可能不知道有乙個taskmanager,並且可以直接將給定的personid設定給任務的assignedpersonid。所以,如何禁止它?在ddd領域有很多討論,這有些有用的模式。我們不會很深入,但是會提供乙個實現的簡單方式。

我們可以按如下更改task實體:

public

class task : entity

//...other members and codes of task entity

public

void assigntoperson(person person, itaskpolicy taskpolicy)

}

我們更改了assignedpersonid的setter為protected。所以,在task實體類之外將不能更改它。新增乙個assigntoperson方法,接收乙個person和task plicy。checkifcanassigntasktoperson方法檢查是否為有效的分配,如果無效則丟擲乙個合適的異常(它的實現在這裡不重要)。然後應用服務方法將變為如下所示:

public

void assigntasktoperson(assigntasktopersoninput input)

我們注入了itaskpolicy作為_taskpolicy並把他傳遞給assigntopersion方法。現在,沒有第二種方式分配乙個任務到人了。我們應該總是使用assigntoperson方法,並且不能跳過業務規則。

返回主目錄

ABP官方文件 十八 領域服務

領域服務 或者服務,在ddd模式中 是被用來執行領域操作或者業務規則的。eric evans 在他的ddd書中這樣說過 乙個好的service應該有以下三個特徵 與領域概念相關的操作不是entity或value object 的乙個自然部分 介面是根據領域模型的其它元素定義的 操作是無狀態的。領域服...

ABP官方文件翻譯 3 5 規約

規約 建立規範類 使用倉儲規約 組合規約 討論介紹 規約模式是一種特別的軟體設計模式,通過使用布林邏輯將業務規則鏈結起來重新調配業務規則。維基百科 尤其是,它通常用來為實體或其他業務物件定義可復用的過濾器。示例 在這個部分,我們將看到規約模式的必要性。本部分是通用的,和abp的實現沒有必然的關係。假...

ABP官方文件翻譯 3 2 值物件

值物件 介紹 展現領域描述性層面且沒有概念性身份的物件稱之為值物件。eric evans 和實體相反,實體有身份標示 id 值物件沒有身份標示。如果兩個實體的身份標示是不同的,那麼就認為他們是不同的物件 實體,即使他們的所有屬性都是一樣的。考慮兩個不同的人有相同的名字 姓氏和年齡,但是他們是不同的人...