I am trying to decide whether to use a Domain Service or an Entity method for a function. Please see the code below:
public class Customer
{
private readonly Guid _id;
private readonly decimal _expenditure;
private readonly IList<IProduct> _eligibleProducts = new List<IProduct>();
public IEnumerable<IProduct> EligibleProducts
{
get { foreach (var product in _eligibleProducts) yield return product; }
}
public void AddProduct(IProduct eligibleProduct)
{
_eligibleProducts.Add(eligibleProduct);
}
}
The customer adds eligible products to the _eligibleProducts collection via the AddProduct method.
In order to determine what the eligible products are; I believe there are two options:
Option 1 - Domain Service
public class OfferCalculator : IOfferCalculator
{
public IEnumerable<IProduct> CalculateEligibility(Customer customer, IList<IProduct> products)
{
return products.Where(x => x.IsEligible(customer));
}
}
In this case the application service will get the eligible products from the Offer Calculator and then call Customer.Add to add the offers individually.
If I wanted to add more specific offers in future then I could have to do this (I believe):
BlackFridayOfferCalculator
ChristmasOfferCalculator
EasterOfferCalculator
I would have to add an interface on a domain service called IOfferCalculator for this.
Option 2 - Entity method
Please see the code below, which is added to the Customer class (customer class shown above):
public IEnumerable<IProduct> DetermineEligibility(IList<IProduct> availableProducts)
{
return availableProducts.Where(x => x.IsEligible(this));
}
If I wanted to add more specific offers in future then I could have to do this (I believe):
BlackFridayCustomer
ChristmasCustomer
EasterCustomer
I would have to add an interface on an entity called ICustomer for this.
I am trying to use the principle of least astonishment.