18

I am currently at the beginning of developing a large web application mainly containing an Angular SPA and an OData WebAPI that has access to a backend layer.
We're at an early stage and have begun to implement the first classes including a Model.dll that is in a common namespace so that it can be accessed by all layers.
We are now discussing about those DTOs within the model. Some say that using interfaces is absolutely neccessary, so the code would be like this:

namespace MySolution.Common.Model
{
    public interface IPerson
    {
        int Id { get; set; }
        string Name { get; set; }
        ...
    }
}

namespace MySolution.Common.Model
{
    public class PersonDTO : IPerson
    {
        public int Id { get; set; }
        public string Name { get; set; }
        ...
    }
}

So that's it. Just simple DTOs with no more intelligence.
I am now asking myself if this is really a good approach, because I don't see the necessity of using the interface here.
What are the advantages with this? Testability was mentioned, but is it even necessary to test DTos? Dependency Injection should also not the point.
Any enlightenment would be very helpful. At the end learning new stuff and approaches is always good...

Simon Linder
  • 3,378
  • 4
  • 32
  • 49
  • 2
    There's no reason to use an interface if you don't need it. This is overcomplicating what should be a simple object. – Josh L. May 19 '15 at 16:23
  • 1
    If the *DTO* is simply a list of properties, I see this pointless. If you had some kind of repository, then you would interface this to replace a DB connection for a fake representation, for example. If you had `Person GetPerson()`, you could have the DB version and Fake version. – Christian Phillips May 19 '15 at 16:24
  • You might pop a marker interface on a DTO (`FooDto : IAmADto`) for type constraints and mappings, but otherwise, what purpose is it serving? There's no abstraction here, depending on `IPerson` gives you exactly the same level of coupling as depending on `Person`. – Iain Galloway May 19 '15 at 16:41

5 Answers5

10

DTOs transfer state - that's it. Injecting them via a container or mocking them for testing seems pointless (if that's the motivation) and totally unnecessary. Don't do it.

Big Daddy
  • 5,160
  • 5
  • 46
  • 76
3

As an example, further to my comment above:

Interface IRepo
{
  Person GetPerson(int id);
}

Public class DbRepo : IRepo
{
  public Person GetPerson(int id){//get person from database}
}

Public class FakeRepo : IRepo
{
  public Person GetPerson(int id)
  {
    return new Person {Id = id, Name = "TestName"};
  }
}

You would use a FakeRepo with some mock objects for testing purposes.

Christian Phillips
  • 18,399
  • 8
  • 53
  • 82
0

I have this situation, where i'm writing a api that should be loosely coupled, because I can adapt any of its parts to behave different, like changing the storage, or alter a number of parameter from a request, so it can have another behavior without affecting what already exist.

With this in mind, is valid have a interface for the DTO, because on another time it could change its properties to carry more data, and you have only to implement a abstraction where you will use this new implemented dto, be to map the new parameters, use in a service to register a record.

Then you do the bindings of the interface(abstraction) to new implementations of the dto and the places that will have modifications.

Then you don't change the behavior of you program and don't make alterations on what already exist.

So you have to think too how will be you api.

0

DTOs may inherit properties from multiple interfaces and using interfaces may reduce casting data between components and modules, especially in the boundaries of a single solution.

Also, rules are often applied on interfaces, so DTOs should use them.

0

I'm new to coding for web, so this may be going the wrong direction, but I've got a DTO from a database, and I want to expose different bits of it for different views. I've encoded this using interfaces on the single DTO (using conditional serialization to ensure only the bits I want are exposed). I'm also using interfaces on incoming data structures so I can use the same DTO, but mock it in my unit tests.

  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community May 12 '22 at 01:02