Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to organize and name DTOs that are used as Data Contracts in a WCF web service

We are using DTOs as Data Contracts in our WCF web service. The purpose for these DTOs is to expose only the information that is relevant for a specific API method.

What I am seeking from you guys is some advise on the best practices here.

For example, consider the following simple model:

class Order
{
    int CreatedBy { get; set; }
    DateTime CreatedOn { get; set; }
    string Description { get; set; }
    int Id { get; set; }
    string Name { get; set; }
}

Assuming our API allows a consumer to Create, Update and Get an Order, we have created the following DTOs. DataMember and DataContract attributes are eliminated for simplicity.

Create method: A user cannot specify the Id and CreatedOn properties, so the DTO looks like this:

class CreateOrderData
{
    int CreatedBy { get; set; }
    string Description { get; set; }
    string Name { get; set; }
}

Update method: A user cannot specify the Id, CreatedOn and CreatedBy properties, so the DTO looks like this:

class UpdateOrderData
{
    string Description { get; set; }
    string Name { get; set; }
}

Get method: A user should be able to see everything for the Order, so the DTO looks like this:

class OrderData
{
    int CreatedBy { get; set; }
    DateTime CreatedOn { get; set; }
    string Description { get; set; }
    int Id { get; set; }
    string Name { get; set; }
}

So here are my questions:

  • Assuming there are more properties in Order model and lot of those properties are shared between "Create" and "Update" DTOs, does it make sense to have these classes extend from a common base class? If yes, should the "Get" DTO (OrderData) also extend from that class? If we do that, doesn't it leave these DTOs too dependent on each other?

  • If all the properties are common between "Create" and "Update" DTOs, should we still create two different DTOs? If yes, why? If not, (this is just a naming question now) what should the "CreateOrUpdate" DTO be called so that the name is obviously different from the "Get" DTO?

  • Is it OK to suffix all the DTOs with something like "Data" or "DataObject" or "Dto"?

  • Are we on the right track here? If not, how can be make this design better?

Update:

I think I don't like the inheritance in DTOs because the base class will also be exposed in the WSDL and the client will be able to see it and instantiate it which seems dirty to me (see this: WCF Serialization with object inheritance?). How about using Interfaces in DTOs to enforce common properties instead of inheritance? Since DTOs should not have any behavior in them, we are not losing much by replacing inheritance.

like image 604
Sumit Garg Avatar asked Aug 16 '12 01:08

Sumit Garg


1 Answers

Since this is a lot about personal preferences, I would do this ..

  1. I would not create a common base class since that would not adhere to L in SOLID. If you are concerned about DRY, then you could create a aggregation instead.

  2. If all properties are common, then it just makes sense to create a Save that takes that object, the order Dto class will have a key property(ies) that would indicate if its an existing order or not.

  3. I would suffix all with Dto, because a lot of Dto class names are same as domain classes, they get confusing since they will exist in the same method together. Then you can decorate your Dtos with DataContract(Name="Order", Namespace="htp://yourdomain/.."]. This way they will be exposed to outside world according to your own preference.

I have been in multiple projects that use the same general architecture, i generally use AutoMapper to map dtos to domain. It has worked great for me !

like image 103
np-hard Avatar answered Nov 09 '22 13:11

np-hard