2011-07-13 77 views
2

我正在使用DI和ORM處理ASP.NET MVC應用程序的模型。最近,我一直在研究將所有業務邏輯寫入服務層的優點和缺點,同時將實體中的邏輯特定於實體類本身。在實體類中聲明的方法顯然是在實體的特定實例上調用的,因此只能在實例從查詢實例化到ORM時才能調用。如何以及應該在哪裏消費域對象方法?

比方說,我有一個Product實體,我聲明瞭一個ApplyDiscount方法。鑑於從控制器的操作方法傳入產品的ID,我必須首先使用此ID查詢產品實例,然後調用ApplyDiscount方法。但是查詢代碼應該在哪裏發生?在我的服務層中聲明方法需要ID,查詢Product實例,然後在該實例上調用ApplyDiscount是否是一種有效的做法?還是應該將代碼放到其他地方?

最終,我想知道是否在嘗試避免胖服務層時查詢服務層中的代碼並修改代碼實體類中生成的實體是普通/正確的實現&貧血症領域模型。

在服務層有沒有查詢代碼一共打敗目的?

+0

如果有人能夠提供討論這個問題的參考資料,那將會很好。 – NoChance

回答

0

它並沒有達到目的,但你最終將功能(特別是驗證)遷移到服務層,而不是必須的。

通常,您希望驗證發生在最早的點;也就是說,如果您被授予了無效的ID,您需要確保在通過邏輯啓動執行鏈之前捕獲了無效的條件。通常,這意味着在控制器中執行查詢並通過服務層傳遞結果對象;這會將查詢的功能隔離到執行鏈中的高級別,並防止您必須在服務層中實現高級排除邏輯(例如,如果整個ID集失效,則可以執行該驗證在你的服務層之外,從而隔離相關的邏輯並且不需要在你的服務層內部做這件事。

一般來說,考慮這個方法:在最早的時候執行對象級驗證和反序列化參考,將您的邏輯儘可能遠離服務層,從而「精簡」服務層。當然,這裏涉及到一定的靈活性,但作爲一般規則,這是一個很好的靈活性。

+0

「這意味着在控制器中執行查詢並將結果對象傳遞到服務層。」所以服務層方法會簡單地將產品作爲參數,並調用'ApplyDiscount'?那麼單行myproduct.ApplyDiscount()服務層方法肯定很薄。控制器需要引用各種存儲庫來查詢並執行驗證。 –

+0

@Sanjeev:是的,假設這是你所有的服務層所做的,那肯定很薄。當你的服務層開始累積邏輯時(這幾乎肯定會隨着時間的推移),這真的開始變得有價值了。無論您在服務層中可以避免的邏輯如何,都會使其變得更簡單。作爲一個方面說明,ApplyDiscount不是你的服務層的功能嗎?你有沒有考慮過它是否應該是? –

+0

那麼ApplyDiscount就是一個例子,但是在這個話題上,我當然可以使用指南來確定哪些方法應該放置在哪裏。 ApplyDiscount不影響任何其他實體,所以我最初假定它屬於Product方法。 –

0

I在這裏沒有真正看到需要服務層。如果邏輯隻影響一個實體,我會把邏輯放在實體本身內部。 (顯然,你不應該相信用戶的輸入,我只是表示這是假設的代碼。)

public ViewResult ApplyDiscount(int productId, decimal percent) 
{ 
    var product = Database.Get<Product>(productId); 
    product.ApplyDiscount(percent); 
    Database.Save(product); 
    return View(product); 
} 

產品:

public void ApplyDiscount(decimal percent) 
{ 
    this.Price = this.Price * (1 - discount); 
} 
+0

你的意思是'this.Price = this.Price *(1 - (percent/100));'對嗎?無論如何,它似乎是一個爭議的問題,您是否已將放置在控制器的操作方法中的代碼置於專用服務層方法中。哪個應該是優先級:在我的服務層中擁有最少的代碼或者在我的控制器中擁有最少的代碼?根據我所瞭解的情況,精簡控制器和瘦服務層都很重要。 –

+0

@Sanjeev呃實際上我會選擇比'percent'更好的名字,因爲它不清楚這意味着什麼。我曾經把所有東西都放在一個服務器中,並且有一個非常薄的控制器,但是我意識到我只是添加了一個不必要的層,因爲我只使用MVC作爲UI。我仍然把所有的邏輯都保存在實體中。 – Ryan

-1

目前我使用一個靜態Find方法對實體例如:

public ActionResult ApplyDiscount(int id, decimal percent) { 

    Product product = Product.Find(id); 

    if (product == null) 
     return HttpNotFound(); 

    var result = product.ApplyDiscount(percent); 

    if (result.IsError) 
     return ViewWithErrors(result); 

    return RedirectToAction("DiscountApplied"); 
} 

ApplyDiscount返回與驗證錯誤,這可以被映射到的ModelState錯誤的對象。

相關問題