2013-06-13 100 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你想知道)。

也许你可以问自己:“我的页面或窗口与该服务相互作用的名称是什么?”是否只有一个或多个?如果更多,他们有什么共同点? 这可以帮助你为你的服务弄清楚一个好名字,从而找出不同的方法来获得每个需要的东西。

告诉我更多。我会很乐意提供帮助。

相关问题