ABP官方文件 十八 領域服務

2021-08-10 04:48:41 字數 2809 閱讀 9069

領域服務(或者服務,在ddd模式中)是被用來執行領域操作或者業務規則的。eric evans 在他的ddd書中這樣說過:乙個好的service應該有以下三個特徵:

與領域概念相關的操作不是entity或value object 的乙個自然部分;

介面是根據領域模型的其它元素定義的;

操作是無狀態的。

領域服務可以被應用服務和其它的領域服務呼叫,但是不可以被表現層直接呼叫(表現層可以直接呼叫應用服務)。

abp 定義了乙個 idomainservice 介面,所有的領域服務都必須實現該介面(記住這是乙個約定),一旦實現了這個介面,那麼領域服務就會通過dependency injection 自動的註冊到系統中作為乙個暫時物件(transient)。

領域服務也可以繼承自 domainservice 類(這是可選的)。

因此,它可以用一些繼承而來的屬性來做日誌記錄,本地化等等;即使你不繼承該類,如果你需要這些屬性也是可以被注入的。

假設我們有乙個任務管理系統,並且我們有這樣的業務規則, 把任務分配到個人。

1. 建立乙個介面

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

public

inte***ce itaskmanager : idomainservice

正如你所看到的,taskmananger 用到了領域物件 :task 和 person 。這裡有一些領域服務的命名約定;例如:taskmananger, taskservice 或者 taskdomainservice 等等。

2. 實現服務

實現如下:

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)

}

我們有如下兩個業務規則:

分配給person的任務狀態應該是active狀態

person最多只能接受3個任務

下面示例為我們展示了應用層是如何呼叫taskmananger:

public

public

void

assigntasktoperson(assigntasktopersoninput input)

}

任務服務層用給定的dto和倉儲資源去檢索相關的task和person,並且將檢索到的結果傳遞給taskmananger(領域服務)。

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

1. 為什麼不只在應用層實現這些邏輯?

你可能會說為什麼不在服務層來實現領域服務裡面的業務邏輯。

我們可以簡單的說因為這根本不是應用層的任務。因為它不是乙個use-case(用例),而是乙個業務操作。我們可以用同樣(分配任務給使用者)的邏輯在不同的用例中。 我們可能會有另外的應用場景,以某種方式更新任務並且這個更新可能包含了分配任務給另外的人。所以,我們可以在這裡用相同的領域邏輯。(說白了就是業務規則重用)還有就是,我們可以有2中不同的ui(手持裝置應用和web應用)可以共享相同的領域。

如果你的業務領域相對簡單,那麼你可以不考慮使用領域服務來實現這些邏輯。在ddd模式中這不是乙個最佳實踐,但abp不會強迫你使用這種設計模式。

2. 為什麼一定要使用領域服務?

看如下示例:

public

void

assigntasktoperson(assigntasktopersoninput input)

寫這個應用的開發人員可能不知道這裡是乙個taskmananger,並直接給任務的assignedpersonid 分配了 personid。 那麼,怎麼阻止這個的發生呢?在ddd社群有很多關於應該採用那種設計模式的**。我們不會做深入的**。但是我們會用乙個簡單的方式來實現。

我們可以改變task實體,如下所示:

public

class task : entity

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

public

void

assigntoperson(person person, itaskpolicy taskpolicy)

}

我們給屬性assignedpersonid 的set設定為protected。所以,這個屬性不可以被外部類修改。新增乙個assigntoperson方法,該方法接受引數型別person和itaskpolicy。itaskpolicy 介面有乙個checkifcanassigntasktoperson 方法來驗證任務是否能分配給person,如果驗證不通過將會丟擲乙個適當的異常。那麼應用層的方法將會如下所示:

public

void

assigntasktoperson(assigntasktopersoninput input)

現在,沒有第二種方式將任務分配給個人。我們應該總是使用assigntoperson 並且不可以跳過該業務規則。

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

領域服務 一些 介紹 領域服務 或者在ddd中單純的服務 用來執行領域操作和業務規則。eric evans在他的ddd書中描述了乙個好的服務有三個特徵 1.與領域概念關聯的操作,但不是實體或值物件的自然組成部分。2.介面的定義依照領域模型的其他元素。3.操作是無狀態的。不像應用服務那樣獲取或返回dt...

ABP官方文件翻譯 3 5 規約

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

ABP官方文件 三 模組系統

abp框架提供了建立和組裝模組的基礎,乙個模組能夠依賴於另乙個模組。在通常情況下,乙個程式集就可以看成是乙個模組。在abp框架中,乙個模組通過乙個類來定義,而這個類要繼承自abpmodule。模組系統當前專注於服務端而不是客戶端。譯者注 如果學習過orchard的朋友,應該知道module模組的強大...