Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using MVVM and DDD in WPF application without having too many classes

Tags:

I have a WPF application where I want to apply MVVM for the presentation layer and DDD for the whole application. I am very confused with how I should apply the architecture. Can you give me some advises as it feels like I have completely messed up at the moment with the following design try:

I have 4 layers:

  • Presentation Layer : This is where my WPF client application lies in.

  • Application Layer : This is where I have my services that's supposed communicate with domain services for business rules and does CRUD. It works simply as an anti-corruption layer between Presentation and Domain layers.

  • Domain Layer : This is where I have my aggregates, domain objects, and some services that reveals business rules, such as IsTooOld(Person person)

  • Infrastructure Layer : This is the lowest layer, infrastructure lies in here, IRepository, IEntity etc..

Let's achieve a simple scenario with those DDD based layers: Have a Person object in a database, map it, CRUD the database, check persons' birthday and show it to the user.


Presentation Layer

I'll start with the WPF part. I create the following classes :

  • PersonView : XAML view of the person

  • PersonViewModel : ViewModel that provides functionality for the PersonView. PersonView binds to this and this ViewModel provides values from PersonModel

  • PersonModel : This is the MVVM model that my PersonViewModel is tightly coupled to.


Domain Layer

This is good enough for the presentation layer. I now want to connect to the database to retrieve a person object to present it.

I must create:

  • PersonEntity in Domain Layer : An aggregate for the database entity, used for mappings with the database. It lies in Domain layer.

  • Person in Domain Layer : This is the domain model of DDD. I'll put some logic here and I don't want to send around entity objects as DDD suggests.


Application Layer

Ok, I already have 3 person models that are pretty similar to each other. How about some more for data access and the services?

  • PersonService in Application Layer : When my presentation layer wants to communicate with this layer it needs to convert its PersonModel (MVVM model) to Person (domain model). This service in application layer then converts Person (domain model) it into PersonEntity (entity object) and does CRUD with the database. This service uses also another PersonService (see below) in Domain layer to check/apply some business rules.

  • PersonService in Domain Layer : This layer works only with Person domain object. It has business-related rules like bool IsTooOld(Person person).


To summarize, I've ended up with 7 classes for a simple scenario :

  1. Presentation.WpfClient.View.PersonView
  2. Presentation.WpfClient.ViewModel.PersonViewModel
  3. Presentation.WpfClient.Model.PersonModel
  4. Application.ApplicationServices.PersonService
  5. Domain.Application.Services.PersonService
  6. Domain.Application.Models.Person
  7. Domain.Application.DbEntities.PersonEntity (the reason I've created this is that I can't use mapping for complex domain objects so I just put some data annotations here instead of mapping domain objects)

This feels very very awkward. I'm not sure how I should re-structure it and benefit both domain driven design and MVVM patterns. I'm really stuck and I'm really looking forward for any advises or real life examples for applying both MVVM and domain driven design. I'm also open for any feedback for naming conventions or strategies for minimizing this much of work for simple operations.

I still have two concrete questions though :

  1. Should I remove models from presentation layer (MVVM models) and use only models from domain layer (DDD models) ? Isn't it violation of MVVM at this point?

  2. Should I merge my entity (database) models with domain models? Isn't it violation of DDD?


Update

Decisions I've taken:

  • Use domain model for MVVM's model (removed PersonModel)
  • Use external mappings for the same model to the database (removed PersonEntity added PersonMappings). Using persistence model is far more costly than simply mapping it. See : http://enterprisecraftsmanship.com/2016/04/05/having-the-domain-model-separate-from-the-persistence-model/ from Vladimir's answer.

Finally it looks like this:

  1. Presentation.WpfClient.View.PersonView
  2. Presentation.WpfClient.ViewModel.PersonViewModel
  3. Application.ApplicationServices.PersonService (crud with some application related logic)
  4. Application.ApplicationServices.Mappings (I have the repository abstractions and mappings here)
  5. Domain.Application.People.Person (person object in it's bounded context, object is smart enough to handle domain logic)
like image 446
U. Bulle Avatar asked Jul 18 '16 07:07

U. Bulle


People also ask

Does WPF use MVVM?

MVVM is the lingua franca of WPF developers because it is well suited to the WPF platform, and WPF was designed to make it easy to build applications using the MVVM pattern (amongst others).

Is Mvvm a DDD?

Model–view–viewmodel (MVVM) is a software architectural pattern that separates the development of the graphical user interface from the development of the business logic or back-end logic. A DDD Entity is something that has identity and type in a business context.

Is WPF MVVM or MVC?

MVVM (Model-View-ViewModel)It is based on the Model-view-controller pattern (MVC), and is targeted at modern UI development platforms (WPF and Silverlight) in which there is a UX developer who has different requirements than a more "traditional" developer.


2 Answers

This is way too many classes for a single concept.

Should I remove models from presentation layer (MVVM models) and use only models from domain layer (DDD models) ? Isn't it violation of MVVM at this point?

Yes, this is a preferable solution is many cases, especially if you don't use a communication mechanism like WCF. No violation here as MVVM doesn't impose a particular implementation of the model part.

Should I merge my entity (database) models with domain models? Isn't it violation of DDD?

Also, yes. Separating an entity into two (domain entity and "persistence" entity) usually leads to over-complication and anemic domain model. Here's more on this: Having the domain model separated from the persistence model.

Overall, I recommend you to look at this example. This looks like exactly what you need: a fully-fledged application written in WPF with the use of MVVM and DDD.

like image 133
Vladimir Avatar answered Sep 18 '22 16:09

Vladimir


DDD is most beneficial in handling comlex business problem. In real project, it should be used in more flexible way deponding on how complex the domain is. I would like to use a multiple-strategies approach to adopt it.

  1. For most of case which mostly is about CRUD data with few change in data structure. I would only use:

    Presentation Layer : ViewModel
    Service Layer: ViewModel<->Domin object
    Domain Layer: Domain object same as Entity

  2. For more complex Domain, where there are many important and reusable business logic on Domain object, then I would add core service (like your Domain.Application.Services.PersonService).

  3. If there are also complex business logic needed for process data for easier mapping data between Presentation Layer and Domin Layer. I would add another model in Service Layer, similar as your Presentation.WpfClient.Model.PersonModel.

So basically the architecture you have righ now is ready for handling the case that your Person domain is very complex in your project. But I can't see it so far from your description.

To answer your questions:

  1. You can remove the Presentation.WpfClient.Model.PersonModel in your MVVM models. It doesn't violate MVVM because in this case, your Domain Object is the Model, And you have Presentation.WpfClient.ViewModel.PersonViewModel as ViewModel.

  2. You can merge Entity with Domain object if your Person domain doesn't have complex business logic.

like image 45
codigube Avatar answered Sep 18 '22 16:09

codigube