WPF Application using MVVM design
I'm using EF as my ORM exposed via a service layer to my front end.
Reading around everything I've read says I should implement automapper in the service layer, but I don't see how that makes sense here.
The ViewModel is the one I wish to differ from the data entities surely so I should do the mapping in the ViewModel?
Or should I be doing it twice (seems overkill) ie map the EF entities to DTOs for the Service to pass to the Front End which then converts them into the ViewModel objects.
I wouldn't bother with DTOs or Automapper in an MVVM client application in the first place. Just use EF types as Model types, and build ViewModels that compose Model types together.
But I wouldn't be concerned at all about coupling between the ViewModel and and Model. The ViewModel is already a later of indirection between the View and the Model/Service layer, and you're almost always deploying all the parts together. It's generally acceptable for a ViewModel to include Model types directly.
But if you do want to put Automapper somewhere, it belongs between the EF types and the Model types, just like it would be if your Services layer was a REST service and you wanted to use DTOs instead of EF Entity types. In that case you may want to change the REST service without redeploying the application, and so having DTOs allow you to make database/EF changes without changing the data that the client receives.
Related
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 :
Presentation.WpfClient.View.PersonView
Presentation.WpfClient.ViewModel.PersonViewModel
Presentation.WpfClient.Model.PersonModel
Application.ApplicationServices.PersonService
Domain.Application.Services.PersonService
Domain.Application.Models.Person
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 :
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?
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:
Presentation.WpfClient.View.PersonView
Presentation.WpfClient.ViewModel.PersonViewModel
Application.ApplicationServices.PersonService (crud with some application related logic)
Application.ApplicationServices.Mappings (I have the repository abstractions and mappings here)
Domain.Application.People.Person (person object in it's bounded context, object is smart enough to handle domain logic)
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.
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.
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
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).
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:
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.
You can merge Entity with Domain object if your Person domain doesn't have complex business logic.
For your first question, using the domain layer models as MVVM models is not a violation of MVVM (See definition of Model here)
For more elaboration on the subject and an answer to your second question see this: Entities VS Domain Models VS View Models
In my WPF application I'm using the MVVM pattern and the repository pattern. I have a repository that provides a list of aircraft objects. From a user perspective, I want to display these aircrafts in several different ways (e.g. on a map, in lists, in textual form, etc..), and also allow the user to filter the objects. To achieve this I have built views and viewmodels for each of the different ways of representing the data.
My problem now is that I'm not sure what the best practice is for making the list of aircraft objects available for all the different viewmodels. Here's some of the alternatives I've considered:
1.Inject the repository into each viewmodel, and then get all the objects from the repo.
2.Inject the repository into a MainViewModel that retrieves all the objects from the repo, and then inject the object collection into all other viewmodels that needs it.
So in sum: I have a set of viewmodels that all make use of the same collection of model objects. What is the best practice for sharing this collection between the viewmodels when using the repository pattern?
In a WPF application I'll typically create service objects which encapsulate repositories which in turn contain a session object each, but I use dependency injection to inject the actual implementations. One of the major benefits of doing this is that everything can be easily mocked for unit testing, but another one is that you now have total control over the scope of these objects. If you're pulling your data from a database then you'll have different strategies for session management depending on whether you're developing a windows app vs a web site (say) and in enterprise applications this requirement will change even within the same code base. There's a good article on Germán Schuager's blog discussing the pros and cons of various session management strategies but for WPF applications using one session per form seems to be a good one. If you're using something like Ninject then you simply scope your ISession object to the view model for your top-level "page" and then all the objects within the logical hierarchy for that page can create their own repositories without needing to know about each other. Since they're all sharing the same session object they're also sharing the same entities in the repository cache and thus the model is now being shared by multiple view models. The only thing that remains is to add property notification to the entity classes in your domain layer so that changes made by one view model propagate through to the others, but that's a topic for another post (hint: your DB layer should provide some mechanism for injecting your own wrapper proxies to add property change notification automatically using things like Castle DynamicProxy etc).
The general rule of thumb is that EACH view should have it's own ViewModel, you can reuse ViewModels via inheritance or adding properties but again a view "DESERVES" it's own ViewModel.
You can have your views leverage interfaces, your viewmodels can implement interfaces.
We have a complex composite financial application where we needed to share various model objects across viewmodels, So we took an approach: we created a high level Model Object which holds collections of other model entities. This high level model is returned/populated in servicelayer. We share this high level model object in many viewmodels and with many PRISM modules using event aggregator .
So in your case you may have a AircarftsData Model, which can maintain collection of aircrafts. you can populate this model using your repository. Then You can pass this AircarftsData in various viewmodels.
We have shipped our application in production with this design and faced no issues as such. One thing you might want to be careful of Memory leakage of this Model object. If somehow any child object of this Model is leaked in memory then whole high level model may remain in memory.
Your data should be located in some place... (Service, Database, File, Etc...).
In that case, you should have a class which manage yours client requests:
GetAllAircrafts, Create, Update, Etc...
This class somtimes called XXXService.
I think that this is where you should expose your collection of models.
This service can be injected to the view models and share the collection of models through a get property (Maybe as a read only collection...?)
Good luck !
I've been wondering what lives in the community for quite some time now;
I'm talking about big, business-oriented WPF/Silverlight enterprise applications.
Theoretically, there are different models at play:
Data Model (typically, linked to your db tables, Edmx/NHibarnate/.. mapped entities)
Business Model (classes containing actual business logic)
Transfer Model (classes (dto's) exposed to the outside world/client)
View Model (classes to which your actual views bind)
It's crystal clear that this separation has it's obvious advantages;
But does it work in real life? Is it a maintenance nightmare?
So what do you do?
In practice, do you use different class models for all of these models?
I've seen a lot of variations on this, for instance:
Data Model = Business Model: Data Model implemented code first (as POCO's), and used as business model with business logic on it as well
Business Model = Transfer Model = View Model: the business model is exposed as such to the client; No mapping to DTO's, .. takes place. The view binds directly to this Business Model
Silverlight RIA Services, out of the box, with Data Model exposed: Data Model = Business Model = Transfer Model. And sometimes even Transfer Model = View Model.
..
I know that the "it depends" answer is in place here;
But on what does it depend then;
Which approaches have you used, and how do you look back on it?
Thanks for sharing,
Regards,
Koen
Good question. I've never coded anything truly enterprisey so my experience is limited but I'll kick off.
My current (WPF/WCF) project uses Data Model = Business Model = Transfer Model = View Model!
There is no DB backend, so the "data model" is effectively business objects serialised to XML.
I played with DTO's but rapidly found the housekeeping arduous in the extreme, and the ever present premature optimiser in me disliked the unnecessary copying involved. This may yet come back to bite me (for instance comms serialisation sometimes has different needs than persistence serialisation), but so far it's not been much of a problem.
Both my business objects and view objects required push notification of value changes, so it made sense to implement them using the same method (INotifyPropertyChanged). This has the nice side effect that my business objects can be directly bound to within WPF views, although using MVVM means the ViewModel can easily provide wrappers if needs be.
So far I haven't hit any major snags, and having one set of objects to maintain keeps things nice and simple. I dread to think how big this project would be if I split out all four "models".
I can certainly see the benefits of having separate objects, but to me until it actually becomes a problem it seems wasted effort and complication.
As I said though, this is all fairly small scale, designed to run on a few 10's of PCs. I'd be interested to read other responses from genuine enterprise developers.
The seperation isnt a nightmare at all, infact since using MVVM as a design pattern I hugely support its use. I recently was part of a team where I wrote the UI component of a rather large product using MVVM which interacted with a server application that handled all the database calls etc and can honestly say it was one of the best projects I have worked on.
This project had a
Data Model (Basic Classes without support for InotifyPropertyChanged),
View Model (Supports INPC, All business logic for associated view),
View (XAML only),
Transfer Model(Methods to call database only)
I have classed the Transfer model as one thing but in reality it was built as several layers.
I also had a series of ViewModel classes that were wrappers around Model classes to either add additional functionality or to change the way the data was presented. These all supported INPC and were the ones that my UI bound to.
I found the MVVM approach very helpfull and in all honesty it kept the code simple, each view had a corresponding view model which handled the business logic for that view, then there were various underlying classes which would be considered the Model.
I think by seperating out the code like this it keeps things easier to understand, each View Model doesnt have the risk of being cluttered because it only contains things related to its view, anything we had that was common between the viewmodels was handled by inheritance to cut down on repeated code.
The benefit of this of course is that the code becomes instantly more maintainable, because the calls to the database was handled in my application by a call to a service it meant that the workings of the service method could be changed, as long as the data returned and the parameters required stay the same the UI never needs to know about this. The same goes for the UI, having the UI with no codebehind means the UI can be adjusted quite easily.
The disadvantage is that sadly some things you just have to do in code behind for whatever reason, unless you really want to stick to MVVM and figure some overcomplicated solution so in some situations it can be hard or impossible to stick to a true MVVM implementation(in our company we considered this to be no code behind).
In conclusion I think that if you make use of inheritance properly, stick to the design pattern and enforce coding standards this approach works very well, if you start to deviate however things start to get messy.
Several layers doesn't lead to maintenance nightmare, moreover the less layers you have - the easier to maintain them. And I'll try to explain why.
1) Transfer Model shouldn't be the same as Data Model
For example, you have the following entity in your ADO.Net Entity Data Model:
Customer
{
int Id
Region Region
EntitySet<Order> Orders
}
And you want to return it from a WCF service, so you write the code like this:
dc.Customers.Include("Region").Include("Orders").FirstOrDefault();
And there is the problem: how consumers of the service will be assured that the Region and Orders properties are not null or empty? And if the Order entity has a collection of OrderDetail entities, will they be serialized too? And sometimes you can forget to switch off lazy loading and the entire object graph will be serialized.
And some other situations:
you need to combine two entities and return them as a single object.
you want to return only a part of an entity, for example all information from a File table except the column FileContent of binary array type.
you want to add or remove some columns from a table but you don't want to expose the new data to existing applications.
So I think you are convinced that auto generated entities are not suitable for web services.
That's why we should create a transfer model like this:
class CustomerModel
{
public int Id { get; set; }
public string Country { get; set; }
public List<OrderModel> Orders { get; set; }
}
And you can freely change tables in the database without affecting existing consumers of the web service, as well as you can change service models without making changes in the database.
To make the process of models transformation easier, you can use the AutoMapper library.
2) It is recommended that View Model shouldn't be the same as Transfer Model
Although you can bind a transfer model object directly to a view, it will be only a "OneTime" relation: changes of a model will not be reflected in a view and vice versa.
A view model class in most cases adds the following features to a model class:
Notification about property changes using the INotifyPropertyChanged interface
Notification about collection changes using the ObservableCollection class
Validation of properties
Reaction to events of the view (using commands or the combination of data binding and property setters)
Conversion of properties, similar to {Binding Converter...}, but on the side of view model
And again, sometimes you will need to combine several models to display them in a single view. And it would be better not to be dependent on service objects but rather define own properties so that if the structure of the model is changed the view model will be the same.
I allways use the above described 3 layers for building applications and it works fine, so I recommend everyone to use the same approach.
We use an approach similar to what Purplegoldfish posted with a few extra layers. Our application communicates primarily with web services so our data objects are not bound to any specific database. This means that database schema changes do not necessarily have to affect the UI.
We have a user interface layer comprising of the following sub-layers:
Data Models: This includes plain data objects that support change notification. These are data models used exclusively on the UI so we have the flexibility of designing these to suit the needs of the UI. Or course some of these objects are not plain as they contain logic that manipulate their state. Also, because we use a lot of data grids, each data model is responsible for providing its list of properties that can be bound to a grid.
Views: Our XAML definitions of the views. To accommodate for some complex requirements we had to resort to code behind in certain cases as sticking to a XAML only approach was too tedious.
ViewModels: This is where we define business logic for our views. These guys also have access to interfaces that are implemented by entities in our data access layer described below.
Module Presenter: This is typically a class that is responsible for initializing a module. Its task also includes registering the views and other entities associated with this module.
Then we have a Data Access layer which contains the following:
Transfer Objects: These are usually data entities exposed by the webservices. Most of these are autogenerated.
Data Adapters such as WCF client proxies and proxies to any other remote data source: These proxies typically implement one or more interfaces exposed to the ViewModels and are responsible for making all calls to the remote data source asynchronously, translating all responses to UI equivalent data models as required. In some cases we use AutoMapper for translation but all of this is done exclusively in this layer.
Our layering approach is a little complex so is the application. It has to deal with different types of data sources including webservices, direct data base access and other types of data sources such as OGC webservices.
I'm still pretty new to Silverlight, quite new to WCF, and am trying to broaden my horizons into both. I'd like to learn what is considered to be good practices while doing so.
On the client side, I have a Silverlight application. On the server side, I have a database that the Silverlight application will be utilizing. In between the two (okay, it's server-side, but...), I have a WCF service that the client calls upon to get the data from the database.
I have created a class that is marked as a DataContract and is used by the WCF service. That class is an object model populated with data from the database. On the client side, when it requests and receives an instance of this class, it uses the instance data to instantiate and populate a client-defined object that has additional client-defined members.
It's my use of the DataContract that most worries me. To create an instance of an object to be serialized and sent, only to be pillaged for its data so another object can be created seems...inefficient. But if it's considered a good practice I can get past that.
I did consider going the route of a web handler (.ashx) and using a proprietary binary standard to communicate the data, but I think going the WCF route may be more applicable and usable in the future (thinking: job).
I don't see any particular problem with your approach.
In my mind what you're describing is the transfer of data from service to client as a DTO (data-transfer object), and then using that DTO to populate a view model object. It is also quite common for the DTO and view model objects to use varying levels of granularity in terms of the data they represent (typically DTOs will be more coarse grained), and the view model will contain behaviour that is specific to the UI.
You might want to look at tools and frameworks that help in the mapping between DTOs and view model objects. One of my favourites is AutoMapper.
I have some trouble getting my head around how to implement more complex operations in a Domain Service in RIA Services. This is all Silverlight 4, VS 2010 and .Net Framework 4 in Beta 2.
Goal
I wish I could create an operation on my LinqToEntitiesDomainService that would have a signature something like this:
public UnwieldyOperationResult PerformUnwieldyOperation( UnwieldyOperationParameters p );
The idea is that this operation takes a colleciton of parameters and performs rather complex operations which would update different instances and types of the entities that are otherwise manipulated through the DomainService CRUD functionality.
Problem
The immediate problem i hit is that does not seem to be allowed to pass the custom type as parameter to the method, and I suppose something along those lines go for the return value. I want to encapsulate the operation parameters in a DTO for clarity, and this unwieldy operation does not have any corresponding entity in the legacy database that I have wrapped with Entity Framework 4.0 model, which I am in turn basing the Domain Service on.
Is a domain service supposed to deal with only the types that are entities in the underlying EF model? Is it not designed to expose more complex operations like my UnwieldyOperation?
If so, can I build another service somehow that allows both the operation signature and to manipulate the entity framework?
I have understood that only one Domain Service can handle an entity from the model. This has led me to cram all the CRUD and now also the UnwieldyOperation into one Domain Service, although my first idea was to split the service into smaller parts.
If I'd get the operation to work with parameters and return value in the Domain Service, my next wish would be to have the entities that are already loaded in the domain context at the client refresh themselves.
Is there any efficient mechanism for such a thing?
How would you go about to do that?
What I have so far...
In short, this is what I have so far:
I have wrapped an existing legacy database
with an Entity Framework 4.0 model with as
little extra padding/code as
possible. This means right-click, add and generate from database.
I have implemented the simpler CRUD operations in the DomainService and I am using them successfully to display and edit straight forward data. I have some encapsulation of logic through ViewModels in client but I expose the Entity classes directly, but I think this is unrelated to my problem/question.
I have realized that I can't add the UnwieldyOperation in an as straight forward manner as I initially thought... Also I suspect/hope that I have misunderstood some aspects of the Domain Service mechanism, which has led me to the current situation.
One way to go?
Writing this down in a question like this gives me the idea that perhaps I'd go in this direction:
LegacyModelService expose the CRUD operations as I have already done.
Expose the Unwieldy operations in another service. Should I make that a RIA Doamin Service or just plain WCF?
Access the Entity Framework model from the new UnwieldyOperationsService and manipulate the data layer there.
Explicitly reload or refresh the client domain context for the LegacyModelService at the client to reflect the changes that may have resultet from the UnwieldyOperation. What would be a good way get this done?
Check out http://msdn.microsoft.com/en-us/library/ee707373%28VS.91%29.aspx for naming conventions over and above simple CRUD, maybe Invoke or Named Update operations would be suitable?