2

I'm extending an existing application, which has an attempt at a logical tier design, using DTOs, a Services layer (business logic), and a DAL. However, as I'm investigating more about DTOs, my existing system doesn't quite fit what I'm reading about DTOs. For example, my DTOs contain all the properties in the underlying database table. Naturally, on many UI screens, I don't want to show all the properties of the DTO, so I'm doing a lot of dataGridView.Columns(0).Visible = False all over the place.

What I've read about DTOs is that they should only contain the fields that are to be shown/used in a given context (e.g. a particular UI screen). I've also read that you should have different DTOs for creating, updating, and showing the underlying business entity (i.e. these different DTOs for Product) if the fields being shown/used are different for each context.

It's kind of hard to make sense of it all, as many posts/articles do not have a comprehensive explanation or code example. They are all fragments that are hard to put together. Some only give the simple "this is a DTO for Student: Name, ID". Almost no real business entities in a system are that simple.

So my question, while rather general, is: How do you design a solid, maintainable DTO architecture for (for example) a simple business object, such as Product. Let's go by some assumptions:

  1. The Product database table has fields: ProductID, ProductName, IsActive, CreateDate, CreatedBy, UpdateDate, UpdatedBy
  2. Product is created in a screen accessible by system administrators (i.e. the "master list" of products in the system, where the admin enters data for fields ProductID, ProductName, IsActive. (ProductID is sourced from another master data system, so is user-entered.) CreateDate and CreatedBy will be handled by the database.
  3. Once a Product is added to the system, the ProductID cannot be edited. The ProductName and IsActive fields can be edited. The database will handle UpdateDate and UpdatedBy.
  4. The UI screen for Product maintenance, where admins add and update Products, will show a list of all Products and all fields from the database.
  5. The system will need a pick-list of active products, so that they can be added to, for example, an Order. The only fields visible in the UI for the pick-list would be ProductID and ProductName.

I assume that from what I've gathered about DTOs, I'd need one for creating a product, one for updating a product, one for viewing all fields in the pick-list maintenance screen UI, and one for the pick-list itself. Is this accurate? Is there a simpler way using less DTOs? This is where I am lost on the topic.

EDIT: Just adding a comment, a lot of the DTO blog/articles seems to talk about the presentation layer, as it applies to DTOs, in terms of displaying data, and not about gathering data (user input) to send to the database.

EDIT 2: And about the Orders object, should it have a List(Of Product) DTOs? Which one of the many Product DTOs (that I think I need)? Should Orders not have a List(Of Product)? A List(Of ProductSummary) or other DTO?

1 Answer 1

2

The most important thing here to understand is that there is no one best way of organizing your models, so don't stress out about it too much. There's probably other spots in your application that deserve more attention. As long as you are consistent in how you handle the models, you will probably be OK.

Do not confuse your DTO's coming out of a service layer with the "View Models" that your individual web/apps use to create their pages and collect data from the UI.

A given service/repo might have a couple methods that return a common "Product" DTO that maps closely with the data table/structure for Products. But as you point out, not ever page in the apps that make any of those Product calls need all the Product fields. That's where View Models come in.

For a given page, if you want to display a listing of all active Products showing the name/ID of the product, and a link to its details, then you could call the Product Service's function for retreiving 'active' Product DTO's. You then map those Product DTO's to a list of Active Product View Models, which in this case, have just fields for the name, id, and hyperlink URL. Your page/view/whatever only understands how to display these View Models, not your Service DTO. If you can easily re-use View Models across a few different pages, then fine, but don't go crazy trying to extend them, its not worth the hassle.

So based on this, your View Models now provide all the fields your UI needs, and nothing more. Furthermore, they are disconnected from your DTO such that you can change which DTO provides their data, without affecting the usage of the View Models themselves. And they do not have to be mapped to one kind of DTO, they can be hydrated from as many different kinds of DTOs as needed, with different DTO's hydrating different properties on the same View Model.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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