Search code examples
vb.netdto

Should a DTO be located inside the class it works on?


I am still only a moderate level coder. I have reviewed a variety of DTO posts, notably this SO Post. I am also aware of the automapper which is mentioned at the SO Post noted, but I have not yet begun to integrate automapper into my code. But my question is about where a DTO should be located if you are coding it. The 3rd answer at the SO Post noted seem to imply what I have shown below.

I coded something like the simple class structure shown below incorporating the DTO inside the classes. The DTO transfers data between the domain and the storage layer. The nested class DTO is automatically invoked. There would be complementary DTO's to go the other way, as well.

Public Class SqlTaskList
    Inherits TaskList
    <Key> Public Overrides Property TaskListID As Integer
    Friend Function SqlToDomainTaskListModel() As TaskList
        Dim theDomainTaskList As New TaskList
        With theDomainTaskList
            .TaskListID = TaskListID
            .TaskListOwner = TaskListOwner
            For Each singleSqlTask In Tasks
                Dim theDomainTaskItem As New TaskItem
                theDomainTaskItem = SqlTaskItem.SqlToDomainTaskItemModel(singleSqlTask)
                theDomainTaskList.Tasks.Add(theDomainTaskItem)
            Next
        End With
        Return theDomainTaskList
    End Function
End Class

Public Class SqlTaskItem
    Inherits TaskItem
    <Key> Public Overrides Property TaskId As Integer
    Shared Function SqlToDomainTaskItemModel(theSqlTaskItem) As TaskItem
        Dim thedomainTaskItem As New TaskItem
        With thedomainTaskItem
            .TaskId = theSqlTaskItem.TaskId
            .TaskName = theSqlTaskItem.TaskName
            .TaskDesc = theSqlTaskItem.TaskDesc
            .TaskOwner = theSqlTaskItem.TaskOwner
        End With
        Return thedomainTaskItem
    End Function
End Class

It works fine, but I began to wonder why should I have the DTO inside the class. I did it this way because I had seen it done this way in several tutorials/examples I had reviewed when learning how to solve this issue.

I'm not that adept at instinctively thinking about memory that is being used, but it occurred to me that every time the classes above are instantiated, they not only take up the data space necessary for the data, they also load up the DTO methods. Would it be better to have the DTO methods outside of the Classes so they are only instantiated when they're needed? Since that may add a little code it seems there may be a tradeoff involved, but I'm not sure. Is there a mechanism I am supposed to use that would only load the DTO's once no matter how many times the classes are instantiated? The classes above are relatively inconsequential, but larger classes would seem to have more impact, yes?

I apologize if this is otherwise an obvious question, but I would like help understanding the issues here.

Clarification added after initial post: My specific question is whether or not it is better from a memory usage (not file) point of view to locate the DTO inside the class it specifically converts, or should the DTOs be in separate classes? Although I mentioned tradeoffs above, I don't see this as an opinion question.

I'm asking if memory used when instantiation takes place is significantly higher when the DTO is inside the class? I don't think this is an opinion - I'm trying to ask about the facts of the situation. Is memory usage higher or not?

It's definitely more convenient elsewhere in the code to invoke the DTO when it is available as a method of the same class. But does that benefit come with the cost of using up more memory than would otherwise be required if the DTOs are in their own class? I'm trying to understand if what works well in a simple application of the class later becomes an active memory problem when the application scales up.

I'm having difficulty picturing in my mind what's going on during execution with a storage layer. Is it the case that the classes above will only be instantiated during storage operations so there won't likely be multiple instantiations at the same time leading to the conclusion where the DTO is doesn't matter? Or in the case of a web app, could there be a large number of simultaneous instantiations which means the DTOs could be instantiated many times, unnecessarily using up memory space?

I'm concerned that in simply coding the storage layer in a straightforward manner I'm unwittingly opening myself up to a memory usage problem downstream.


Solution

  • First off, based on the code you have above, your DTOs are not in the same class. You have two separate classes but it looks like they might be in the same exact file.

    It is really up to you to decide whether you want your classes in different files or all in one. I tend to recommend one class in one file. This is for readability and segregation purposes. It doesn't change any of the memory footprint except for maybe a single code file. This will eventually all be compiled into a DLL. So there really isn't any instantiation of the classes taking place until you "new" it up. I tend to recommend separate files in different folders and namespaces to organize your code so it's easy to navigate. Putting all your code into a single file tends to make it harder to read as your code base gets larger. It also will lead to the potential of classes not making sense where they are. They end up being in this one file, but could easily belong to another due to the way that things get organized.

    The examples from other posts showing them in a single place are usually just for illustrative purposes for ease of reading on a platform like SO. It's hard to put code from a bunch of separate files and display them in a meaningful way here.

    As far as only loading a single instance of a class, you're basically talking about the Singleton pattern. There are plenty of resources out there you can use to look that up.