Reputation: 2724
I've the following code:
The entity that represents a Customer.
public class Customer
{
public int CustomerId { get; set; }
public string Name { get; set; }
public int CountryId { get; set; }
}
The entity that represents a Country:
public class Country
{
public int CountryId { get; set; }
public string Name { get; set; }
}
The service that holds the Customer CRUD operations..
public interface ICustomerService
{
//Save..
//Update..
//Another domain specific operations...
}
To allow users to select the customers country to register it is necessary to provide an operation that returns the list of countries available for selection.
I've the following alternatives:
Put this operation within the ICustomerService, for example GetAvailableCountriesToCustomerRegister ().
Create another service called ICountryService and put this operation in it, along with the CRUD operations.
What should I use? Why?
Upvotes: 0
Views: 50
Reputation: 172786
Put this operation within the ICustomerService, for example GetAvailableCountriesToCustomerRegister ().
Doing so would break three out of five SOLID principles, because (source):
The Single Responsibility Principle is violated, because the methods in each class are not highly cohesive. The only thing that relates those methods is the fact that they belong to the same concept or entity.
The design violates the Open/Closed Principle, because almost every time a query is added to the system, an existing interface and its implementations need to be changed. Every interface has at least two implementations: one real implementation and one test implementation.
The Interface Segregation Principle is violated, because the interfaces are wide (have many methods) and consumers of those interfaces are forced to depend on methods that they don’t use.
But your second alternative isn't much better:
Create another service called ICountryService and put this operation in it, along with the CRUD operations.
This leads to the exact same situation where still all three SOLID principles are violated.
The solution here is to give queries their own abstraction and give each query its own message and implementation, as described here.
Upvotes: 1
Reputation: 572
It's all about cohesion. Names 'ICustomerService' and 'ICountryService' do not reflect the intentions of business. In your case more preferably be called 'IRegistrationService', where you can reflect all your registration functionality. And in this 'RegistrationService' you can reuse your existing repositories. But it is important that the 'RegistrationService' expresses your subdomain.
Upvotes: 0