Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DTO naming conventions , modeling and inheritance

Tags:

c#

dto

nhibernate

We are building a web app using AngularJS , C# , ASP.Net Web API and Fluent NHibernate. We have decided to use DTOs to transfer data to the presentation layer ( angular views). I had a few doubts regarding the general structuring and naming of DTOs. Here's an example to illustrate my scenario. Lets say I have a domain entity called Customer which looks like:

public class Customer     {         public virtual int Id { get; set; }         public virtual string Name { get; set; }         public virtual Address Address { get; set; }         public virtual ICollection<Account> Accounts { get; set; }     } 

Now, in my views/presentation layer I need to retrieve different flavors of Customer like :

1) Just Id and Name 2) Id , Name and Address 3) Id , Name , Address and Accounts

I have created a set of DTOs to accomplish this :

public class CustomerEntry {     public  int Id { get; set; }     public  string Name { get; set; } }  public class CustomerWithAddress : CustomerEntry {     public AddressDetails Address { get; set; } }  public class CustomerWithAddressAndAccounts : CustomerWithAddress {     public ICollection<AccountDetails> Accounts { get; set; } } 

AddressDetails and AccountDetails are DTOs which have all the properties of their corresponding Domain entities.

This works fine for querying and data retrievals ; the question is what do I use for inserts and updates. During creation of a new customer record , name and address are mandatory and accounts are optional ..so in other words I need an object with all the customer properties. Hence the confusion :

1) What do I use for insert and updates? The CustomerWithAddressAndAccounts DTO has everything in it but its name seems a bit awkward to be used for insert/updates.

2) Do I create another DTO .. if I do , wouldn't that be duplication as the new DTO will exactly be like CustomerWithAddressAndAccounts ?

3) Last but not least , does the DTO inheritance strcuture described above seem like a good fit for the requirement ? Are there any other ways to model this ?

I have gone through other posts on this topic but couldn't make much headway. One thing that I did pickup was to avoid using the suffix "DTO" in the class names. I think it feels a bit superfluous.

Would love to hear your thoughts

Thanks

like image 442
Sennin Avatar asked Sep 16 '13 18:09

Sennin


People also ask

How do you name a DTO object?

dto . The name of the Data Transfer Object type should be the name of the runtime type for which the Data Transfer Object is a representation followed by DTO . So for a type Widget , the Data Transfer Object for that type should be WidgetDTO .

What is DTO model?

Data transfer object (DTO), formerly known as value objects or VO, is a design pattern used to transfer data between software application subsystems. DTOs are often used in conjunction with data access objects to retrieve data from a database.

What does DTO stand for in c#?

To accomplish this, you can define a data transfer object (DTO). A DTO is an object that defines how the data will be sent over the network. Let's see how that works with the Book entity. In the Models folder, add two DTO classes: C# Copy.

What is. net DTO?

A DTO (Data Transfer Object) is an object that defines how data will be sent between applications. It's used only to send and receive data and does not contain in itself any business logic.


1 Answers

Recommendation is that you should just have one DTO class for each entity suffixed with DTO e.g. CustomerEntryDTO for the Customer entity (but you can certainly use inheritance hierarchies as per choice and requirements).

Moreover, Add a abstract DTOBase kind of base class or an interface; and do not use such deep inheritance heirarchies for each Address, Account and other properties to be included in child DTOs. Rather, include these properties in the same CustomerEntryDTO class (if possible) as below:

[Serializable] public class CustomerEntryDTO : DTOBase, IAddressDetails, IAccountDetails {     public  int Id { get; set; }     public  string Name { get; set; }     public AddressDetails Address { get; set; } //Can remain null for some Customers     public ICollection<AccountDetails> Accounts { get; set; } //Can remain null for some Customemer } 

Moreover, your DTOs should be serializable to be passed across process boundaries.

For more on the DTO pattern, refer below articles:

Data Transfer Object

MSDN

Edit: In case you don't want to send certain properties over the wire (I know you would need to that conditionally so would need to explore more on this), you can exclude them from the Serialization mechanism by using attributes such as NonSerialized (but it works only on fields and not properties, see workaround article for using with properties: NonSerialized on property). You can also create your own custom attribute such as ExcludeFromSerializationAttribute and apply it to properties you don't want to send every time over wire based on certain rules/conditions. Also see: Conditional xml serialization

Edit 2: Use interfaces for separating the different properties in the one CustomerEntryDTO class. See the Interface Segregation Principle on Google or MSDN. I will try to put a sample explanation later.

like image 65
VSS Avatar answered Oct 10 '22 01:10

VSS