0
votes

Assume we have separate models for Domain and Persistence, one domain model is stored as two persistence model, as given below.

class DomainEntity {
    property1;
    property2;
} 

class PersistenceEntity1 {
    domainProperty1;
    appProperty1;
}

class PersistenceEntity2 {
    domainPproperty2;
    appProperty2;
}

If you see the models there are some extra application properties in the persistence model which doesn't belong in the domain model, e.g. modifiedOn, modifiedBy etc...

Now my question is how to pass these values to the infrastructure layer, since the Repository interface also belongs to the Domain layer, we can't add these properties to its signature.

1
either don't mix domain and application layer attributes in one entity or you may consider of two repositories. one which is finds domain objects and one which acts on the application infos. but i would recommend to don't mix these attributes in one entity. - snap
Repository also belongs to the Domain layer - how so? The Repository Interface: yes but the Repository Implementation: no - Constantin Galbenu
@ConstantinGalbenu that's what I meant, interface. in implementation you can't have different signature, right? - msmani
You can't but you don't need to. Those additional attributes could be kept hidden in the Infrastructure layer. - Constantin Galbenu
(I edited your question: since the Repository interface also belongs to the Domain layer) - Constantin Galbenu

1 Answers

2
votes

The additional attributes that do not belong to the Domain can be added from the Infrastructure, for example from the Repository implementation. In this way, the Domain remain agnostic of infrastructure concerns.

The Repository implementation could get that data from the services that get injected. For example, if the Persistence model needs the current Authenticated user ID to be stored in the modifiedBy then the AuthenticatedUserService should be injected into the Repository implementation.

One simpler example is the modifiedOn that can be set to the Current system date, without any service injection.

As a pseudocode:

// Domain layer
class DomainEntity {
    property1;
    property2;
} 

// Infrastructure layer

class PersistenceEntity1 {
    domainProperty1;
    Date modifiedOn;
}

class PersistenceEntity2 {
    domainPproperty2;
    UserId modifiedBy;
}


class Repository {
    // dependency injection
    constructor(AuthenticatedUserService auth){ 
        this.auth = auth;
    }

    function save(DomainEntity d) {
       PersistenceEntity1 p1 = new PersistenceEntity1(d.property1, Date.current() );

       PersistenceEntity2 p21 = new PersistenceEntity1(d.property1, this.auth.getAuthenticatedUserId() );

       db1.save(p1);
       db2.save(p2);
    }
}