![](/img/trans.png)
[英]Where should I put commonly used data access code with logic not fitting to Repository when using Service classes on top of Repository/UnitOrWork?
[英]How much logic should i put my repository methods when using repository pattern?
我正在與存儲庫進行一些努力。 我正在使用C#和NHibernate。 我的問題是:我的存儲庫在調用save或get之前應該做多少?
例如,我有一個用戶類,它是一個聚合根。 我想調用一個名為“register”的方法,它將添加用戶並根據業務規則設置一些默認值,並創建一些其他實體,這些實體也是“用戶”根的子部分(即地址,組等)。 我應該打電話嗎?
userRepo.Register(newUser);
這將是(忽略明顯的問題):
Regsiter(User newUser){
newUser.SomeProp = "Default Data";
Group g= new Group;
g.SomeProp2 = "Default Data";
newUser.Groups.Add(g);
Session.Save(g);
Session.Save(newUser);
}
或者我應該將注冊放在業務層中並讓它做:
Regsiter(User newUser){
newUser.SomeProp = "Default Data";
Group g= new Group;
g.SomeProp2 = "Default Data";
newUser.Groups.Add(g);
userRepo.Register(newUser, g);// this does session.save on both objects.
}
兩者似乎都有些錯誤。
什么是正確的方法?
編輯-------------------------------
感謝所有的回復。 我不能決定誰是最合適的,因此接受哪個答案。
通常每個人都在說將業務規則放在另一層。 這是有道理的,但我不確定組的數據調用 - 因為組不是聚合根,他們不應該有自己的存儲庫,所以我如何添加和保存它們? 在我的項目中,將一個組添加到用戶的組集合中不會自動在數據庫中創建該組; 我還需要在對象上調用session.save。 所以我把它作為userRepo.SaveGroup(g)放入用戶倉庫?
如果我在另一個層中有一個createGroup(),那么它將需要使用它自己的repo或用戶。 還是我很厚?
就個人而言,我將存儲庫模式保留為sprocs的替代品。 所以我的存儲庫會有getById(int id)
, save()
, add(DomainObject obj)
等方法。
在業務層中,我有userManager.registerUser(字符串用戶名,/ * params等* /)。 這將創建域對象。 此方法只會調用數據層中的add()
方法。
簡而言之,業務層是業務層,數據層是數據層。
您首先使用存儲庫模式的動機是什么? 通常,存儲庫是對象持久性邏輯的抽象。 它從(通常)數據庫中檢索項目,還處理更新,插入和刪除。
如果您正在編寫測試以檢查某些邏輯並且不想訪問數據庫,那么您需要模擬哪些對象? 通常是存儲庫。
在方案A)中,您無法測試使用正確的默認數據創建的新用戶,而無需直接訪問數據庫。 因此,我建議將所有業務邏輯保留在存儲庫之外,並采用第二種設計
確定您希望Register方法的位置,可能在UserServices類中。 您可以將對象創建委派給UserFactory。 在CreateNewUser()方法中,為用戶和Groups集合設置默認值。 然后調用UserRepository.Save(newUser)來保存數據。
// UserServices class
public void Register(User newUser)
{
// add custom registration stuff.
_userRepository.Save(newUser);
}
// Application code
User user = UserFactory.CreateNewUser();
_userServices.Register(user);
// UserFactory
public User CreateNewUser()
{
// all new user, group creation
}
從您的代碼示例中,我將Register方法稱為服務操作。 作為服務操作,它將屬於服務或業務組件,而不是存儲庫。 根據Evans(DDD成名),存儲庫是存儲在數據庫中的實體的類似集合的接口。 一般的想法是,您通過存儲庫提供對實體的基本CRUD訪問,以從ORM工具等較低級別的數據訪問詳細信息中抽象出其余代碼。
對於您使用Register的示例...您的服務方法將驗證輸入,構建User對象,然后調用您的存儲庫以“添加”您的新實體到“存儲庫”(可能是一個數據庫......但也可能是其他...就你的域名而言,它無關緊要......它只是一個存儲庫。)
我看到兩個潛在的“錯誤”問題(因為你沒有真正表明你認為他們的錯誤)。
如果問題圍繞在用戶注冊方法中保存組,或者將用戶保存在組方法中,則應將這些方法分成不同的方法。 (即Register()將調用RegisterGroup()或GetGroup()
如果問題圍繞在用戶真正准備從概念上保存事物之前保存事物,那么跟蹤他們想要添加的內容並等待直到調用整個“保存”方法,然后將任何這些信息存儲到存儲中。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.