Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where to call repository.update in DDD?

I have a real scenario that is a perfect Domain Model design. It is a field that has multiple quadrants with different states on every quadrant. So my aggregate root is the field. Now i have one important question: I want to have a persitant ignorat domain model, which i think makes sense. so where should i call the update on the repository methods? not in the domain model, right? So how should the aggregate root child entities update in the database when there is no change tracking proxy of this objects and the repository should not be called in the entities? Or do i misunderstand the domain model pattern?

is my question clear? :) thank you in advance best laurin

like image 427
LaurinSt Avatar asked Jan 10 '13 10:01

LaurinSt


2 Answers

The "application code" should call the repository. How the application code is hosted is an infrastructure concern. Some examples of how the application code might be hosted are WCF service, as a Winforms/WPF application, or on a Web server.

The repository implementation is responsible for tracking changes to the aggregate root and its child entities as well as saving them back to the db.

Here is an example:

Domain Project

public DomainObject : AggregateRootBase //Implements IAggregateRoot
{
    public void DoSomething() { }
}

public IDomainObjectRepository : IRepository<DomainObject>, IEnumerable
{
    DomainObject this[object id] { get; set; }
    void Add(DomainObject do);
    void Remove(DomainObject do);
    int IndexOf(DomainObject do);
    object IDof(DomainObject do);
    IEnumerator<DomainObject> GetEnumerator();
}

Implementation Project

public SqlDomainObjectRepository : List<DomainObjectDataModel>, IDomainObjectRepository
{
    //TODO: Implement all of the members for IDomainObjectRepository
}

Application Project

public class MyApp
{
    IDomainObjectRepository repository = //TODO: Initialize a concrete SqlDomainObjectRepository that loads what we need.
    DomainObject do = repository[0]; //Get the one (or set) that we're working with.
    do.DoSomething(); //Call some business logic that changes the state of the aggregate root.
    repository[repository.IDof(do)] = do; //Save the domain object with all changes back to the db.
}

If you need to transactionalize changes to multiple aggregate roots so the changes are made on an all or nothing basis, then you should look into the Unit of Work pattern.

Hope this helps clarify things!

like image 165
Aaron Hawkins Avatar answered Sep 18 '22 15:09

Aaron Hawkins


The Aggregate Root (AR) is updated somwehere. Using a message driven architecture, that somewhere is a command handler, but let's say for general purpose that is a service. THe service gets the AR from a repository, calls the relevant methods then saves the AR back to repository.

The AR doesn't know about the repository, it is not its concern. The Repository then saves all the AR modficications as a unit of work (that is all or nothing). How the Repo does that, well, that depends on how you decided your persistence strategy.

If you're using Event Sourcing, then the AR generates events and the Repo will use those events to persist AR state. If you take a more common approach, that AR should have a state data somewhere exposed as a property perhaps. It's called the memento pattern. The repository persist that data in one commit.

Bu one thing is certain: NEVER think of the persistence details, when dealing with a Domain object. That is don't couple the Domain to an ORM or to some db specific stuff.

like image 34
MikeSW Avatar answered Sep 19 '22 15:09

MikeSW