I am trying to setup my application’s structure in VS and I want to “try” and future proof it to a reasonable level. This application will be a WPF re-write of an old Winform app that had followed no conventions. No Layers, Tiers, Acronyms, etc…
It is a fairly largish Enterprise Application. I planned to use Linq To SQL as my DB’s are and will most likely always be MS SQL. Also I have an existing skill set with it.
I want to follow MVVM and DDD the best I can but I get confused on the structure of my application when combining these. Let me try and illustrate with some examples.
When I follow MVVM my folder structure may look like this:
Views
Models
ViewModels
Helpers
but how does that fit into a simplistic DDD layered approach where my Project Structure might resemble this:
MyApp.UI
MyApp.Domain
MyApp.Data
Do I put the Models
in the Domain layer or do I have 3 versions of say Person
? This leads to another question of where would I put my Repository and mappings of DB Object to Domain Object? I would assume Data…
Views
I get would go in UI but would ViewModels
also?
Finally, where would I be embedding my Business Logic?
I found the following on CodePlex,DDD Example ,and it has been some help but seems to be for a Web App though that may not matter and is my ignorance shining through.
Don’t get me wrong, I know I can have as many folders and call them whatever I want. I am trying to figure out where to place things so that this will be scale-able, not what those places necessarily are called.
The heart of my question might be shown like this.
I have tblPerson
object generated by *.dbml
. This is obvious and would belong in my “Data” layer.
Now I would have Model, DTO, Domain Model, or whatever it’s called in a seperate Layer(project?) called Person
. I would need a Mapper
for Person
to tblPerson
that I’m not sure where to put.
Then, I’ll have a ViewModel for, say, EditPerson
that would have it’s own properties that it pulls from Person
but possibly more as well.
Finally I’d have a View that was bound to that ViewModel….
To be clear that paragraph is FILLED with my assumptions and guesses and I am hoping someone will help clear the air for me or offer there insights so that 6 months to a year from now I am not kicking myself more than I need to.
2
MVVM is a UI pattern and is used in a client.
The parts of the domain in DDD that are used in the client are probably (a part of) the Model
The View and ViewModel are client only.
I put Repositories in (or near) the Model because they synchronize the Model to the back-end.
Yes, many times this will result in multiple Person classes in different namespaces. They might start out very similar but might end up very different after a couple of iteration or releases.
EDIT
To clarify the part about Repositories and to explain more about the positioning of Business Logic
If you are creating a system that contains a separate client and server-side/back-end Repositories can be used in the client and the server. In the client to provide an abstraction of the server(s) and in the server to provide an abstraction of other servers and data sources. It is just a pattern.
As for Business rules: if you use those in the client make sure you enforce them in the server as well. Never trust a client. Business rules in the client allow for speedy input validation and prevent round-trips to the server.
I do think that DDD belongs on the server side and ‘leaks’ to the client.
You have right direction in choosing MVVM design pattern for WPF application.
Do I put the Models in the Domain layer?
Yes, your models can be placed in domain
Where would I put my Repository and mappings of DB Object to Domain Object?
Your repositories can be placed in the layer where your Domain is placed. Your mapping objects (also called DTOs – domain transfer objects) should be placed in your service layer and you may use a powerful mapping tool AutoMapper to easily map your domain objects to DTOs.
ViewModels also?
Your ViewModels should be placed on your client side (layer). You may construct your viewmodels from one or more DTOs, depending on your views.
Regarding DDD , i would suggest to read about this and clarify to you really need to have Domain-Driven Design pattern. here is a discussion that 95% of all software applications fall into the “not so good for using DDD” categories.
Edit: reference has been added above, and thanks go for @Den!
3
Before we delve into what goes where, let’s talk about what each layer should be doing.
The selling point of MVVM is the binding between the view and the view-model. The goal here is to eliminate logic within the view.
Like the View, the Model should be pretty lightweight and used only to access the information (data) that is necessary for the view-model to operate. The Model can blend access to different data sources, but it shouldn’t have business logic. In most cases, you have a single data store to hit. In some cases you don’t. When you don’t, it’s appropriate to use the Model to obscure the source of the data from the VM.
An implicit point of MVVM is that the data is already stored and your project isn’t responsible for maintaining its organization. Some projects are lucky enough to get away with that assumption, most of the projects I’ve worked on haven’t been so lucky. Suffice it to say that Data is another layer we’ll have to contend with.
I would lay out my project like this:
project.Views
project.ViewModel
project.Model
project.DataStructs
and this layer can be added in as needed:
project.Helpers
I’m separating the Helpers from the rest of the stack so it doesn’t get confused as being a layer of your application stack.
Disclaimer: I’m not a DDD expert, but I understand the general gist and see the value in the approach.
Your Domain is going to be the problem set that you are considering.
The Domain Models are going to correspond primarily to the ViewModels that you create; a little bit within the Views; and a small chunk within the Model / DataStructs.
So how is that going to work out?
IF you have the ability to change up the existing data structures, then the new ones you create should correlate to the problem you’re trying to solve. Got a customer object? Then you should have a / some tables related to the Customer. Got invoices or products? Same story – tables and structures that map to those business objects should be created.
The Domain will be expressed through your ViewModel objects and the Views you present of those objects. If you need to edit Customer records then you’ll have a VM for handling that task.
On to your questions:
- Don’t try to overlay DDD onto MVVM. It just isn’t going to work. DDD isn’t a layout pattern, it’s an approach to viewing your overall problem.
- Repository and Mappings will live in either project.Data or project.Model as appropriate.
- Don’t have a layer called UI unless that’s what you want to call project.Views.
- Business Logic will go in the View-Model.
2