Stato dominio permanente senza esposizione dei provider sottostanti

2

Lavorare su un'applicazione DDD in cui ho bisogno di mantenere lo stato. Ecco un esempio molto semplice:

public interface IRoot {
  public int Id { get; }
  void UpdateValue(int value);
}

public interface IState {
  int Id { get; }
  int CurrentValue { get; }
}

public class AggregateRoot : IRoot {

  private State _state;

  internal AggregateRoot(State state){
    _state = state;
  }

  public int Id { get { return _state.Id; } }

  public void UpdateValue(int value){
    _state.CurrentValue = value;
  }

}

public class State : IState {

  internal State(int id){
    Id = id;
  }

  public int Id { get; internal set; }

  public int CurrentValue { get; internal set; }

}

Usando l'interfaccia interna setter / getter only, posso garantire che lo stato non venga modificato al di fuori della logica di business implementata nella root del dominio. Ho creato un factory / builder all'interno dello stesso progetto per creare un'istanza di nuove radici con stato.

Il mio problema arriva quando si tratta di persistere / caricare lo stato da qualche archivio dati. Sto cercando di mantenere i dettagli di implementazione della persistenza completamente separati dal dominio, quindi creo un'interfaccia repository per mantenere lo stato:

public interface IStateRepository {
    void Save(IState state);
    void Delete(int key);
    IState Get(int key);        
}

Dal momento che sto usando le interfacce senza setter nel repository, non posso aggiornare l'ID di stato al salvataggio o popolare direttamente un oggetto. L'implementazione IStateRepository si trova in un progetto completamente separato, quindi anche id Ho cambiato repository per utilizzare direttamente lo stato, non avrei ancora accesso alle proprietà senza usare reflection.

L'unica soluzione che posso pensare che mi consentirebbe comunque di avere una separazione netta è l'implementazione di un DTO che funga da oggetto di mappatura tra il dominio e i livelli di persistenza, ma ciò non sembra corretto. In sostanza, creo un oggetto duplicato con le proprietà dell'oggetto State, ma con i setter pubblici.

Sicuramente c'è qualche schema ovvio che mi manca?

    
posta aasukisuki 18.07.2018 - 14:50
fonte

1 risposta

1

Un progetto separato che implementa l'IStateRepository è un buon modo, ma è necessario considerare che è davvero necessario creare una classe interna nel progetto Data che implementa IState.

Nota, dal momento che le interfacce sono contratti, immagina se questo progetto si sta sviluppando da due persone che dovrebbero lavorare rispettando queste regole, altrimenti, non c'è modo di garantire la capacità di comunicare tra queste coppie, significa che esse basta conoscere la definizione di IState, ma ognuno dovrebbe creare un oggetto concreto che garantisca questa definizione.

The only solution I can think of that would still allow me to have clean separation is to implement a DTO that would act as mapping object between the domain and the persistence layers, but that doesn't feel right. I'd essentially be creating a duplicate object with the properties of the State object, but with public setters.

Purtroppo, penso che sarà la soluzione migliore per te! Tuttavia, se si crea una classe interna nel progetto Data che implementa IState, non è necessario eseguirne il mapping. Perché entrambi questi progetti comprendono implicitamente il tipo.

In ogni caso, considera che anche se entrambi implementano IState, non sono le stesse cose. In termini concettuali, oggetto dati e oggetto dominio hanno uno scopo diverso.

Inoltre, posso proporre di non separare il progetto se il tuo sistema non è troppo grande, facendolo, il problema è scomparso. Di solito lo faccio.

Spero sia stato utile per te, pensaci e buon codice!

    
risposta data 18.07.2018 - 21:07
fonte

Leggi altre domande sui tag