領域服務(或者服務,在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模組的強大...