Reputation: 2167
A lot of discussions, like this and this, go with RICH DOMAIN MODEL
and there are 2 strong reason about amenic, like 1 and 3:
Now let's say that I need to make sure that I need to validate that the product exists in inventory and throw exception if it doesn't.
so there is a question: If we don't need an object to be dependent on ISomeRepository
like service, can we just make this:
public void Order.AddOrderLine(IEnumerable<Product> products, Product product)
{
if(!prosucts.Contains(product))
throw new AddProductException
OrderLines.Add(new OrderLine(product));
}
and call it like this:
Order.AddOrderLine(ISomeRepository.GetAll(), product);
Upvotes: 1
Views: 568
Reputation: 9017
It sounds like there's a missing concept in your domain here. I'd think about introducing some kind of StoreInventory
entity, such that products move out of the inventory and into an order (this is called 'picking' in many commerce domains).
interface StoreInventory
{
IEnumerable<Product> AvailableProducts { get; }
Product PickProduct(guid productId); // This doesn't have to be an Id, it could be some other key or a specification.
}
void Order.AddOrderLine(StoreInventory inventory, Product product)
{
if (!inventory.AvailableProducts.Contains(product.Id))
throw new AddProductException();
var item = inventory.Pick(product);
OrderLines.Add(new OrderLine(item);
}
This would seem to be more closely aligned to reality to me. But as always in DDD, only your domain experts can tell you how things are supposed to flow.
This also seems more extensible in the future, for example with this model it would be easy to introduce multiple stores - each with their own inventory.
Upvotes: 1
Reputation: 12849
If you read about DDD, you would see that Repository is core concept of DDD. In DDD, repository is part of domain and says what kind of behavior the domain requires from it's persistence to work. In your case, you could simply pass the repository into the method and have the method pull the necessary data.
public void Order.AddOrderLine(ISomeRepository repo, Product product)
{
if(!repo.ProductExists(product))
throw new AddProductException
OrderLines.Add(new OrderLine(product));
}
// call it like
Order.AddOrderLine(someRepository, product);
I think the problem of your confusion is that repository, or more precisely, it's abstraction, is often tied to the persistence itself. Which is actually misconception caused by misunderstanding of the whole pattern. Correct repository consists of 2 parts: the abstraction, usually represented by interface, which defines what kind of operations the domain requires from the persistence. And the concrete implementation, that implements those operations over used persistence technology.
Upvotes: 0