Ilan Y
Ilan Y

Reputation: 107

RavenDB load documentmapping to POCO or domain aggregate root class?

If I have this class:

public class Order
{
    public string Id { get; private set; }
    public DateTime Raised { get; private set; }
    public Money TotalValue { get; private set; }
    public Money TotalTax { get; private set; }
    public List<OrderItem> Items { get; private set; }

    public Order(Messages.CreateOrder request, IOrderNumberGenerator numberGenerator, ITaxCalculator taxCalculator)
    {
        Raised = DateTime.UtcNow;
        Id = numberGenerator.Generate();
        Items = new List<OrderItem>();
        foreach(var item in request.InitialItems)
            AddOrderItem(item);
        UpdateTotals(taxCalculator);
    }

    private void AddOrderItemCore(Messages.AddOrderItem request)
    {
        Items.Add(new OrderItem(this, request));
    }

    public void AddOrderItem(Messages.AddOrderItem request, ITaxCalculator taxCalculator)
    {
        AddOrderItemCore(request);
        UpdateTotals(taxCalculator);
    }

    private void UpdateTotals(ITaxCalculator taxCalculator)
    {
         TotalTax = Items.Sum(x => taxCalculator.Calculate(this, x));
         TotalValue = Items.Sum(x => x.Value);
    }
 }

Then is this acceptable at the service layer?:

Order order = documentStore.Load<Order>(id);

I would like to have one class per aggregate root and not to have to define a separate Order POCO with just the properties in order to serialize and deserialize. Note that I have changed the serialization mechanism to include private setters.

Upvotes: 1

Views: 112

Answers (1)

Adrian Thompson Phillips
Adrian Thompson Phillips

Reputation: 7141

This is fine, it's recommended by Ayende as the first tip in his My 10 tips and tricks with RavenDB.

The argument to not use the repository pattern is very convincing and there is little reason to use the repository pattern when using DDD and RavenDB together.

I've used this technique directly from my domain/application layers and it has so far cut down on the amount of code to maintain and made the project much simpler. I still get my Unit of Work and something that feels very much like a strongly typed repository when using the RavenDB IDocumentSession.

The only reason I can think of for keeping the repository pattern with RavenDB, would be to reveal the intention of what your repository should be allowed to do, when creating repositories for read-only data, etc. If you have a good Ubiquitous Language, then there should be little need to express that audit entries must be read only (and where would the business requirement come from to code it otherwise anyway?).

Upvotes: 1

Related Questions