Search code examples
c#repositorypersistenceaggregateroot

Persisting Order AggregateRoot Without Using ORM


I have an aggregate root Order with its child aggregates OrderLine, i am trying to implement repository pattern without using ORM frameworks, only ADO.Net, and to say the truth my brain stack is a bit overflowed.

One way that i learned was to use Projac, its idea is to record events inside aggregate root and than use them to save changes to database. Now i am trying to avoid using Projac with events and want to implement repository which will detect changes inside AggregateRoot and save them to database. Is there any best practice to do it without using ORM? I really couldn't find anything, all example that i have seen are using EF or Nhibernate, or other ORMs.

Thank you.

Order Aggregate Root:

    // Skipped most of properties
public class Order
{
    public int OrderID { get; private set; }
    public bool IsFinalized { get; private set; }
    public List<OrderLine> OrderLines { get; private set; }

    public void FinalizeOrder()
    {
        IsFinalized = true;
    }

    public void AddOrderLine(int stockItemID)
    {
        var orderLine = new OrderLine(0, OrderID, stockItemID);
        OrderLines.Add(orderLine);
    }
}

OrderLine Aggregate:

    // Skipped most of properties
public class OrderLine
{
    public OrderLine(int orderLineID, int orderID, int stockItemID)
    {
        OrderLineID = orderLineID;
        OrderID = orderID;
        StockItemID = stockItemID;
    }

    public int OrderLineID { get; private set; }
    public int OrderID { get; private set; }
    public int StockItemID { get; private set; }
}

OrderCommanHandler and Commands:

    public class OrderCommandsHandler :
    ICommandHandler<FinalizeOrderCommand>,
    ICommandHandler<AddOrderLineCommand>
{
    private readonly IOrderRepository orderRepository;

    public OrderCommandsHandler(IOrderRepository orderRepository)
    {
        this.orderRepository = orderRepository;
    }

    public void Handle(AddOrderLineCommand command)
    {
        var order = orderRepository.FindByID(command.OrderID);
        order.AddOrderLine(command.StockItemID);
        orderRepository.Save(order);
    }

    public void Handle(FinalizeOrderCommand command)
    {
        var order = orderRepository.FindByID(command.OrderID);
        order.FinalizeOrder();
        orderRepository.Save(order);
    }
}

public class AddOrderLineCommand : ICommand
{
    public AddOrderLineCommand(int orderID, int stockItemID)
    {
        OrderID = orderID;
        StockItemID = stockItemID;
    }

    public int OrderID { get; private set; }
    public int StockItemID { get; private set; }
}

public class FinalizeOrderCommand : ICommand
{
    public FinalizeOrderCommand(int orderID)
    {
        OrderID = orderID;
    }

    public int OrderID { get; private set; }
}

And OrderRepository:

    public class OrderRepository : IOrderRepository
{
    public Order FindByID(int id)
    {
        // This is simple
        throw new NotImplementedException();
    }

    public void Save(Order order)
    {
        // Help me implement
        throw new NotImplementedException();
    }
}

Solution

  • Is there any best practice to do it without using ORM? I really couldn't find anything, all example that i have seen are using EF or Nhibernate, or other ORMs.

    This is really nothing to do with CQRS, Aggregates or Domain Driven Design. It's just "how do I save an object to a database". I'd recommend looking into micro-ORMs such as PetaPoco or Dapper. These give you a very lightweight abstraction to work with and have plenty of examples of how to save an object to a database. They're kinda a halfway house between working with ADO.net and a full-blown ORM such as nHibernate or EntityFramework.