2013-06-13 99 views
4

在工作中,我已經投入開發一個傳統的enterprice應用程序,由於設計不穩定和不穩定,這些應用程序在過去幾個月仍處於生產和停滯狀態。C#應用程序體系結構-EF5和理解服務層

因此,我們已經開始使用EF5並將一些設計模式/圖層應用於我們的應用程序。

我在努力理解的是:在我們的例子中,服務層應該做什麼?它會過度架構,還是會提供一些好處而不添加不必要的複雜性?

讓我們來告訴你什麼是我們這麼遠:

  • 我們引入了EF(代碼先用波蘇斯)來映射我們的傳統數據庫(效果相當好)
  • 我們創建庫對於我們需要在新的數據層最東西(具體實施中,我沒有看到關於使用通用回購關心的分離 - 任何形式的好處。)

現在,在特定情況下,它是關於價格計算一篇文章 - 通過從弧線獲得價格直接或從文章所在的組(如果沒有指定價格)。它變得複雜得多,因爲還有不同的價格表(取決於訂單的完整價值)以及取決於客戶誰也可以有特價等。

所以我的主要問題是:誰是負責獲得正確的價格?

我的想法是: 順序必須知道它包含的項目。另一方面,這些物品必須知道他們的價格是什麼,但是訂單不知道如何計算物品的價格,只需要總結其成本。

的我此刻的代碼

Excert:

ArticlePrice(POCO,映射很快就被通過流體API交換)

[Table("artikeldaten_preise")] 
public class ArticlePrice : BaseEntity 
{ 
    [Key] 
    [Column("id")] 
    public int Id { get; set; } 

    [Column("einheit")] 
    public int UnitId { get; set; } 

    [ForeignKey("UnitId")] 
    public virtual Unit Unit { get; set; } 

    [Column("preisliste")] 
    public int PricelistId { get; set; } 

    [ForeignKey("PricelistId")] 
    public virtual Pricelist Pricelist { get; set; } 

    [Column("artikel")] 
    public int ArticleId { get; set; } 

    [ForeignKey("ArticleId")] 
    public virtual Article Article { get; set; } 

    public PriceInfo PriceInfo { get; set; } 

} 

文中的價格信息庫:

public class ArticlePriceRepository : CarpetFiveRepository 
{ 
    public ArticlePriceRepository(CarpetFiveContext context) : base(context) {} 

    public IEnumerable<ArticlePrice> FindByCriteria(ArticlePriceCriteria criteria) 
    { 
     var prices = from price in DbContext.ArticlePrices 
        where 
         price.PricelistId == criteria.Pricelist.Id 
         && price.ArticleId == criteria.Article.Id 
         && price.UnitId == criteria.Unit.Id 
         && price.Deleted == false 
        select price; 

     return prices.ToList(); 
    } 
} 

public class ArticlePriceCriteria 
{ 
    public Pricelist Pricelist { get; set; } 
    public Article Article { get; set; } 
    public Unit Unit { get; set; } 

    public ArticlePriceCriteria(Pricelist pricelist, Article article, Unit unit) 
    { 
     Pricelist = pricelist; 
     Article = article; 
     Unit = unit; 
    } 
} 

PriceService(確實有一個horriffic代碼的氣味...

public class PriceService 
{ 
    private PricelistRepository _pricelistRepository; 
    private ArticlePriceRepository _articlePriceRepository; 
    private PriceGroupRepository _priceGroupRepository; 

    public PriceService(PricelistRepository pricelistRepository, ArticlePriceRepository articlePriceRepository, PriceGroupRepository priceGroupRepository) 
    { 
     _pricelistRepository = pricelistRepository; 
     _articlePriceRepository = articlePriceRepository; 
     _priceGroupRepository = priceGroupRepository; 
    } 

    public double GetByArticle(Article article, Unit unit, double amount = 1, double orderValue = 0, DateTime dateTime = new DateTime()) 
    { 
     var pricelists = _pricelistRepository.FindByDate(dateTime, orderValue); 

     var articlePrices = new List<ArticlePrice>(); 

     foreach (var list in pricelists) 
      articlePrices.AddRange(_articlePriceRepository.FindByCriteria(new ArticlePriceCriteria(list, article, unit))); 

     double price = 0; 
     double priceDiff = 0; 

     foreach (var articlePrice in articlePrices) 
     { 
      switch (articlePrice.PriceInfo.Type) 
      { 
        case PriceTypes.Absolute: 
         price = articlePrice.PriceInfo.Price; 
         break; 
        case PriceTypes.Difference: 
         priceDiff = priceDiff + articlePrice.PriceInfo.Price; 
        break; 
      } 
     } 

     return (price + priceDiff) * amount; 
    } 

    public double GetByPriceGroup(PriceGroup priceGroup, Unit unit) 
    { 
     throw new NotImplementedException("not implemented yet"); 
    } 

    //etc. you'll get the point that this approach might be completely WRONG 

} 

我最終的問題是: 如何正確建模我的問題?這是否正確,我是否正在爲我的代碼構建架構? 我的服務層如何正確地看起來像?我寧願有一個ArticlePriceService,一個ArticleGroupPriceService等?但是誰會連接這些部件並計算出正確的價格?例如,是具有「GetPrice」方法的OrderItemService的責任?但是,然後再orderItemService將不得不知道其他服務..

請嘗試爲我提供可能的解決方案有關架構,以及哪些對象/層做什麼。

如果您需要更多信息,請隨時提出其他問題!

+0

如果你能甚至第三你原來的問題,你會得到更多的人閱讀這降低了你的問題一半的大小... – oleksii

+0

我接受建議,但我實在不明白我怎麼能在沒有拿走重要信息的情況下將其裁掉:/ – bberger

回答

0

您確實提出了一個簡單的場景,其中存儲庫本身可能就足夠了。
你有更多的知識庫嗎?
您是否期望您的應用程序增長,並且有更多的存儲庫在使用?

有一個抽象數據層的服務層被我看到的大多數應用程序/示例所使用,並且開銷並不那麼重要。

當您想要從多個不同的存儲庫獲取數據,然後對數據執行某種聚合/操作時,可能會彈出一個使用服務的原因。
然後服務層將提供操作邏輯,而服務使用者不必處理幾個不同的存儲庫。
您還應該考慮可能希望在一個事務中更改一個實體(含義 - 多個存儲庫)的情況,並且僅當所有更新操作都成功時纔將更改保存到數據庫。
這種情況應該暗示使用Unit Of Work Pattern,並且可能會結束使用服務層,以啓用適當的單元測試。

+0

那麼,在我的情況下,價格本身是根據不同來源計算的:它必須考慮來自3個不同存儲庫的ArticlePrices,ArticleGroupPrices和CustomerPrices。它也必須考慮從最貴的價格表所有這些都來了,它必須知道哪個價格表否決了另一個。 我的一些擔心是:我的PriceService將不得不知道所有這些因素,以及它們是如何相互影響.. 另外:我會有一個OrderPriceService知道ItemPriceService哪知道(文章)PriceService? – bberger

+0

很難告訴你如何設計你的系統。存儲庫「JUST」獲取數據以及執行所有邏輯的服務層是非常習慣的。另外,正如我寫的,您應該考慮可能的UPDATE場景,而不僅僅是數據檢索場景。 – Liel

+0

我在'PriceService'處看到你的代碼沒有問題。你爲什麼認爲這是錯的? – Liel

0

當我開始使用對象和體系結構時,我的主要問題是給類提供一個好名字。

對我來說,看起來你的服務應該被稱爲「ShopService」(或類似的東西)。然後你的方法GetByArticle,應該是nammed GetPriceByArticle。

的東西不僅僅是價格更大的改變服務的名稱會更meaningfull,也將解決其他問題的想法(如您的OrderPriceService你想知道)。

也許你可以問自己:「我的頁面或窗口與該服務相互作用的名稱是什麼?」是否只有一個或多個?如果更多,他們有什麼共同點? 這可以幫助你爲你的服務弄清楚一個好名字,從而找出不同的方法來獲得每個需要的東西。

告訴我更多。我會很樂意提供幫助。

相關問題