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.