Fredrick Lackey - 121 - Mar 19, 2014

When laying out the Request and Response objects, is it necessary to use a concrete class for any properties?  For example, would this constitute a valid Response object:

public class GetCountryListResponse
{
    public ResponseStatus ResponseStatus { get; set; }

    public IList<ICountry> Countries { get; set; }
}

Stephen Brannan:

Yes it would work. A __type json propety is added to the json to identify the type. Though I would recommend making that a List<ICountry> instead to lesson the size of the json string. 

Fredrick Lackey:

+Stephen Brannan Beautiful.  The model object was actually what I was hoping for.  Returning a firm List is irrelevant in this instance.

Please never use interfaces as properties in DTO’s, it doesn’t do what you think it does and there’s no good reason for this: 
http://stackoverflow.com/a/10759250/85785

Stephen Brannan:

+Demis Bellot I don’t recommend it either, but if you must as I recall ServiceStack.Text did support it, right?

Doesn’t matter if it’s supported, it provides the worst behavior in all cases. It’s slower, distorts the wire format and ends up more tightly coupled to C# and SS.JSON.

Using concrete collection types generates the same wire format so you can already have the Response DTO on the server returning: 

public class Response {
   public List<Country> Countries { get; set; }
}

and have the client desalinizing it into a different concrete collection, e.g:

public class Response {
   public HashSet<Country> Countries { get; set; }
}

and that still works because the wire format is the same.

Fredrick Lackey:

+Demis Bellot Thanks for the link and feedback.  You’re right.  I was trying to accommodate a bad design.  Glad someone smacked me out of it.

Drazen Dotlic:

@Demis Bellot I didn’t know this, our DTOs all use IList… will have to review that SO comment, thanks for the pointer.

Stefan Tsalapatis:

+Demis Bellot 
In some cases,  the collection is  created in the business logic layer   and the service layer knows only the interface. Why is bad design ?
In general,  I use only Lists or  simply arrays, and always as members of the Response DTO,  but it is  flexible to use interfaces in some cases.
Maybe you could  deserialize the contents into a List<T> ?

You shouldn’t leak interfaces on the wire, it’s not good for any reasons you think it would be and very bad for the reasons above.

In general interfaces on Models are unlikely to be useful, i.e. when was the last time IList<T> provided any benefit over List<T>? 

Stefan Tsalapatis:

+Demis Bellot
When the business layer, a DLL from another team, it updates a collection that the service layer   knows, only as  IList<T>.   In client side  the IList could be deserialized always as List<T>.

+Stefan Tsalapatis so the useful example is that because someone else is returning an IList? and that it’s convertible to a List<T>? why not just use a List<T> in the first place and save all the un-necessary code/conversions?

Either way IList should never be returned on the wire, it’s rarely useful on models in code and is always detrimental on the wire.

Fredrick Lackey:

Gotta find a way to keep this thread alive… (just kidding)

What about inheriting from a BaseRequest or BaseResponse object?  Any negatives about doing this?  For example, if every response should contain ResponseStatus or some other solution-specific attribute.

Stefan Tsalapatis:

+Demis Bellot

Because we implement the  service layer with serviceStack  as a very thin layer,  in the front of  the business-logic. ( not ormlite or other ss stuff).  The Response DTO is created in the business layer. Of course, the IList member  can be converted to List<T>, but it is an extra step and a step from developers, not related with the service developer.  Never mind, what I said is from our experience, maybe others experience is different. As I wrote also in my first comment, it is a rare case, but more flexible if need be.

+Fredrick Lackey my preference is to not hide DTO properties behind inheritance which should be considered a DSL for defining a service contract with, see:
http://stackoverflow.com/a/15369736/85785

On a related note, whenever I need to have custom logic applied to multiple DTO’s I have DTO’s implementing the same interface.