应用服务 - 运营分配

时间:2015-03-11 17:30:05

标签: c# repository domain-driven-design inversion-of-control

我有以下代码:

代表客户的实体。

public class Customer
{
    public int CustomerId { get; set; }
    public string Name { get; set; }

    public int CountryId { get; set; }    
}

代表国家/地区的实体:

public class Country
{
    public int CountryId { get; set; }
    public string Name { get; set; }
}

持有客户CRUD操作的服务..

public interface ICustomerService
{
    //Save..
    //Update..
    //Another domain specific operations...
}

要允许用户选择要注册的客户所在国家,必须提供返回可供选择的国家/地区列表的操作。

我有以下选择:

  • 将此操作放在ICustomerService中,例如GetAvailableCountriesToCustomerRegister()。

  • 创建另一个名为ICountryService的服务,并将此操作与CRUD操作一起放入其中。

我应该使用什么? 为什么呢?

2 个答案:

答案 0 :(得分:1)

  

例如,将此操作放在ICustomerService中   GetAvailableCountriesToCustomerRegister()。

这样做会破坏五个SOLID原则中的三个,因为(source):

  

违反了Single Responsibility Principle,因为这些方法   在每个班级都没有高度凝聚力。唯一相关的事情   那些方法是他们属于同一个概念或者   实体。

     

设计违反Open/Closed Principle,因为几乎每一个   查询添加到系统的时间,现有接口及其   实现需要改变。每个界面至少有两个   实现:一个真正的实现和一个测试实现。

     

违反了Interface Segregation Principle,因为。{   接口很宽(有很多方法)和消费者   接口被迫依赖于他们不使用的方法。

但是你的第二种选择并不是更好:

  

创建另一个名为ICountryService的服务并执行此操作   其中,以及CRUD操作。

这导致完全相同的情况仍然违反了所有三个SOLID原则。

这里的解决方案是为查询提供自己的抽象,并为每个查询提供自己的消息和实现,如here所述。

答案 1 :(得分:0)

这都是关于凝聚力的。名称“ICustomerService”和“ICountryService”并未反映业务意图。在您的情况下,更优选地称为“IRegistrationService”,您可以在其中反映所有注册功能。在这个'RegistrationService'中,您可以重用现有的存储库。但重要的是'RegistrationService'表示您的子域。