3

Using .NET - I have an interface IPerson. This interface is implemented by classes in multiple, separate repositories, e.g. EF6 (EfPerson), custom SQL (SqlPerson), or even custom assembly connecting to a web service (WebPerson).

Assuming rich domain model, my idea is that my lovely rich domain object 'Person' could have a private member variable _PersonDto of type IPerson, supplied via constructor. The members of Person would be the only way to access data from the _PersonDto.

Q. Is there anything actually inherently wrong with that approach? (Assume I'm not lazy loading, and that I will possibly have a service layer for cross-cutting stuff).

Please note I'm using DTO here to simply mean the anaemic objects I get back from my repositories.

  • See also this post. It describes the same thing, programming against data access object interfaces. – Chalky Jul 18 '14 at 7:05
4

A couple of observations.

First, classes (DTO or otherwise) should be data-persistence agnostic. In other words, they should have no awareness of their underlying data persistence mechanism. It worries me that you have three different versions of a Person that are distinguished only by the way they are stored or retrieved.

Second, DTO classes are merely containers, used primarily for movement of data from one place to another. The only reason you might set them via constructor is if:

  1. You wanted them to be immutable, or
  2. You wanted them to be valid on instantiation.

Validation in business systems is normally accomplished elsewhere (it shouldn't necessarily be tied to the Person object, although you can annotate objects with validation information), and in business systems, there's generally no expectation of immutability (most business systems are a big mass of mutable data and business logic).

So for all these reasons, I say the answer to your question is no.

  • Hi, thanks for your answer. Surely my 3 different repositories can return 3 different classes, as long as they implement the abstraction - the IPerson interface? – Chalky Jul 15 '14 at 1:56
  • 1
    Sure, but... Why? The manner in which objects are saved or loaded has nothing to do with their individual characteristics. That's the very definition of tight coupling. – Robert Harvey Jul 15 '14 at 1:57
  • So the various repositories should all return the same class - such as a persistence class (I'll stop calling it a DTO), and dispense with the interface? – Chalky Jul 15 '14 at 19:28
  • I have the feeling that we're talking past each other. I never said anything about a persistence class, nor did I mention interfaces. I merely said that the DTO should not have any knowledge of how it is persisted, and that setting a DTO in the constructor is unnecessary. – Robert Harvey Jul 15 '14 at 19:41
  • Yes, I think you're right! See my original question re my abuse of the term 'DTO' - 'Please note I'm using DTO here to simply mean the anaemic objects I get back from my repositories' – Chalky Jul 15 '14 at 19:52
1
+50

There's nothing wrong with the backing state DTO approach, in fact it's recommended by some DDD people.

However, populating a domain object from heterogeneous sources is not the main reason for it. It's more about solving the entity encapsulation vs persistability paradox by having an object that is easily accessible and mappable by ORMs.

EfPerson/SqlPerson/WebPerson and the IPerson interface are unnecessary IMO, because the backing state object is just a dumb data bag that will contain exactly the same thing in all cases.

Data gathering and mapping logic should rather be placed in anticorruption layers between the various source systems and your own system, or in different concrete Repository implementations.

  • Thanks, good answer. So my DTO should be a class, rather than an interface? I found the interface approach quite useful thus far. – Chalky Jun 22 '15 at 12:54
  • It should definitely be a class. The interface is useful when you have behavior and not just data, is it the case in your current implementation ? – guillaume31 Jun 22 '15 at 13:27
  • ...and the reason it's useful so far, it enables my EF classes (for example) to retain their persistence-specific attributes (yeah I know I can move most/all of that into fluent API), and I just just abstract away via my IPerson (it's an IDto really) interface. EF, SQL, Web (CRM), etc. are implementors of my IDtos, and this allows the shape of their implementation classes can be quite different. – Chalky Jun 22 '15 at 13:30
  • Okay, I wasn't thinking about attributes. Seems legit to me then (except the name IPerson which sounds... awkward) – guillaume31 Jun 22 '15 at 13:36
  • I think you should refrain from introducing methods in that interface and classes though, they are not supposed to do anything. Even if attributes can be hints for an external tool, hydrating themselves is not their job. – guillaume31 Jun 22 '15 at 13:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.