Timsen
Timsen

Reputation: 4126

Where to convert entities/models to viewmodels in MVVM?

In MVC it's pretty straignforward:

Client makes a request, controller asks buiseness logic to do some fancy stuff, buiseness logic asks repository to return some data, then repository returns data and buiseness logic is responsible for converting data from entities to viewmodels, which are returned to the client.

In MVVM I'm pretty much lost, since the viewmodel itself is responsible for making requests to the buiseness logic, there is no "middle layer" like the Controller. I could implement mappers in the buiseness logic project but since viewmodels are responsible to ask buiseness logic for data, it would create circular reference.

So where do I have to make this "magic" happen?

Upvotes: 4

Views: 4308

Answers (4)

eran otzap
eran otzap

Reputation: 12533

I'm gonna try to give some context with a simple example.

Be aware that all the code below is conceptual only and written here and not in VS.

Think of your ViewModel as a wrapper for your model. Your model is exposed by a property so you can bind to it or to it's properties from your view.

Your ViewModel :

  public class SomeEntityViewModel : NotificationObject
  {
       private SomeEntity _someEntity;
       public  SomeEntity SomeEntity
       {
           get{ return _someEntity;}
           set
           {
               _someEntity = value;
               RaisePropertyChanged("SomeEntity");
           }  
       }  
  } 

Now lets assume you send a request to your server and await a response.

Let's also assume you have an higher object (like a parent ViewModel) which initiates your VM :

  public class SomeEntityContainerViewModel : NotificationObject
  {
      public ObservableCollection<SomeEntityViewModel> Items;

      public void async OnRequestNewEntity() 
      {
         SomeEntity newEntity = await _someEntityService.CreateSomeEntityAsync();
         var vm = new SomeEntityViewModel{ SomeEntity = newEntity};
         Items.add(vm);
      }
  }

Your SomeEntityContainerView of which SomeEntityContainerViewModel is the DataContext :

  <UserControl>
      <Button Command="{Binding RequestNewEntityCommand}" />
      <ItemsControl ItemsSource="{Binding Items}" />
  </UserControl>

Your SomeEntityView of which SomeEntityViewModel is the DataContext :

    <UserControl>
        <TextBlock Text="{Binding SomeEntity.Name}" />
    </UserControl>

In it's most simplistic design :

Your model needs to be "dumb", only data. Your ViewModel is the closest equivalent to a Controller and it will handle the logic and it is the component that will wrap (not convert) your model in a view model.

In the example above we have some higher object a parent ViewModel which initiates our ViewModel.

That's equivalent to a Controller's scope which has other nested controllers under it in the DOM.

Upvotes: 4

Mark Feldman
Mark Feldman

Reputation: 16148

Your question is the wrong way round. The view model represents the logic behind the users interaction with your application, so the question really should be "how does the view model acquire entities and models when user interaction requests them?". The answer is: "With a dependency injection framework, e.g. Ninject". This allows you to scope entities to pages in a WPF app, to web requests in an MVC or WCF app, to singletons in any external console utilities or to mocked objects in your testing framework...and all without your view models knowing or caring about how those entities or the services providing them are being created or work internally.

Upvotes: 0

slugster
slugster

Reputation: 49985

In MVVM the "business layer" that you refer to is the "model" - in fact anything after the viewmodel is considered part of the "model". However in any work I've ever done, I've always split this model into n-tier, usually with a controller style class that uses services to retrieve data entities from a data repository.

Where to convert entities/models to viewmodels?

You don't, strictly speaking. The viewmodels can contain the entities (i.e. the VM has an ObservableCollection of them), or a viewmodel can wrap an entity (useful in list controls where you may need to show options or execute actions on a per row basis).

The MVC approach to an entity is a bit dirtier than MVVM, you end up with a richer business model rather than a nice lean entity. In MVVM that "richness" is mostly split out and handled by the viewmodel, and you try and keep the data entity as simple as possible (yes you can include things like validation in the entity, but you should only do it when necessary, other times the validation should be taken care of in the VM or somewhere in the model).

Upvotes: 0

Devon Burriss
Devon Burriss

Reputation: 2532

Based on the mvvm-light reference I am assuming a WPF app here. I the 1st paragraph you mention your business logic (I will call it a service from here) is responsible for converting to the view model. I would say the service should have no knowledge of the view. So in that case the controller (or a mapper called by controller or model binder) would handle the mapping.

In MVVM (my opinion here while trying to draw a comparison for you) the ViewModel acts a lot like the controller as it goes and gets the model, maps and binds to an observable. It is then also the model that binds to the view (the view model that is often used in mvc).

So I think the trick here for you is to move where the mapping should occur. The services should not have any knowledge of the views. They are not coupled to the views then which is a good thing.

Upvotes: 0

Related Questions