Tuesday, April 5, 2011

Does this Entity Repository Service example fit into Domain-Driven Design?

I would like to know if you find the following pattern meaningful in domain driven design.

The domain layer consists of model and repository. The application layer consists of services that handles queries from the user interface, or from controllers in the Model-View-Controller pattern.

Details of the structure:

// Assembly Model:
public class Phrase
{
    public int PhraseId { get; private set; }
    public string PhraseText { get; private set; }

    public Phrase(string phraseText) { this.PhraseText = phraseText; }

    public void SetId(int phraseId) { this.PhraseId = phraseId; }
}

// Assembly Repository (references assembly Model):
public interface IPhraseRepository
{
    Phrase SavePhrase(Phrase phrase);
    Phrase GetPhrase(int phraseId);
}

// Assembly Services (references assemblies Model and Repository):
public class PhraseService
{
    private IPhraseRepository _phraseRepository;
    public PhraseService(IPhraseRepository phraseRepository)
    {
        _phraseRepository = phraseRepository;
    }
    public Phrase SavePhrase(string phraseText)
    {
        Phrase phrase = _phraseRepository.SavePhrase(new Phrase(phraseText));
        // doing other things like sending mail, logging, etc.
        // ...
        return Phrase;
    }
}

Particularly, would it make sense to move the method into the Phrase entity class? In that case, how would that be called?

EDIT:

The example above has been modified after the answer from moffdub and the comment from Adeel Ansari. The changes are highlighted.

I would like to ask about the added IPhraseRepository.GetPhrase(phraseId) and how you would include that?

From stackoverflow
  • The repository should take in a Phrase, not a string. I'm also not sure why the SavePhrase method returns a Phrase. I tend to make such methods void methods.

    Also, be wary of making every property in your domain model have public getters and setters. That can lead you to an anemic domain model.

    Adeel Ansari : Think you don't have an id before persisting the entity. You must need the entity back, in that case. Think of auto-number type in the database, or sequence.
    Ole Lynge : @moffdub and @Adeel Ansari : Thanks for both your replies. I learned something, I think, and will update with a suggested improvement.
    Ole Lynge : How do I serialize with private setters? See my question about that here: http://stackoverflow.com/questions/455884/conflict-between-avoiding-anemic-model-and-allowing-serialization.
  • Just some thoughts:

    SetId(int phraseId) should not be public

    Phrase could implement IPhrase (or IPhraseAggregate) which would not expose SetId(..)

    SavePhrase(Phrase phrase) could (should?) return void if the reference to the phrase entity stays "valid" after saving:

    public void SavePhrase(string phraseText)
    {
        Phrase phrase = new Phrase(phraseText); // NOTE: keep a reference to phrase
        this._phraseRepository.SavePhrase(phrase); // NOTE: returns void
    
        return phrase; // NOTE: assume the repository sets the phrase.PhraseId
    }
    

0 comments:

Post a Comment