Why implement an interface on viewmodel and view in mvvm

20,955

Solution 1

Basically, we need interfaces for injections only. There are 2 ways:

  • Inject ViewModels to Views

It will mean that the ViewModel no longer has any back reference to the View. This means when unit-testing the ViewModel you don't need a mock view. Additionally it makes the code cleaner, in that in the constructor of the View, it simply sets the DataContext to the ViewModel that was injected.

  • Inject Views to ViewModels.

It avoids to keep workflow logic into the Presentation layer. It means that the Application layer keeps responsible for the application workflow. This way the workflow logic is highly coupled with the Views and so it is quite impossible to write unit test for this.

Solution 2

first a very nice comment from Rachel regarding viewmodel first:

Remember, with MVVM your ViewModels are your application. The View is just a pretty interface that allows users to interact with your ViewModels.

1) IView is a violation of MVVM for me, but codebehind is of course allowed for ui stuff. viewmodel should just have no reference to the view. see 1st comment from Hasith

2) see my blockquote

3) i'm with you - i never use something like that in my projects

4) pls do MVVM the easy way - no coupling, use di, ioc, commanding, behaviors and for me the most important: viewmodel first:)

Share:
20,955
Hari Subramaniam
Author by

Hari Subramaniam

Updated on July 13, 2020

Comments

  • Hari Subramaniam
    Hari Subramaniam almost 4 years

    I am quite new to MVVM pattern so please bear with me. I have seen implemnentations in wpf +mvvm + prism where all the views tend to have an IView as top most interface. Then the views in the respective modules have a view specific interface like IViewA, IViewB etc which implement the IView interface. Even the viewmodel has IViewModel top most interface and the subsequent modules have IViewAViewModel , IViewBViewModel etc that inherit from the IViewmodel. IViewmodel has a reference to Iview and the Iview has a reference to IViewModel.

    namespace xxx.xxx.infrastructure
    {
    public interface IView
    {
      IViewModel ViewModel {get;set;}
    }
    
    public interface IViewModel 
    {
      IView View {get;set;}
    }
    
    public abstract class ViewModelBase : IViewModel, INotifyPropertyChanged
    {
    
       public IView View {get;set;}
    
       public ViewModelBase(IView view)
       {
         View = view;
         View.ViewModel = this;
       }
       //INotifyPropertyChanged left out
     }
    }
    
    namespace xxx.xxx.Modules.Customer
    {
       public interface ICustomerDetailsView : IView
       {
    
       }
    
       public partial Class CustomerDetailsView : UserControl, ICustomerDetailsView 
       {
           public CustomerDetailsView ()
           {
             InitializeComponent();
           }
    
           //Is this implementation acceptable?The view is supposed to have zero code in       the code behind.....
            public IViewModel ViewModel
            {
              get
              {
                return (ICustomerDetailsViewViewModel)DataContext; 
              }
              set
              {
                 DataContext = value;
              }
            }
    
        }  
    
        public interface ICustomerDetailsViewViewModel : IViewModel
        {
           string Message {get;set;}
        }
    
         public class CustomerDetailsViewViewModel : ViewModelBase,       ICustomerDetailsViewViewModel 
        {
          //Will be injected by unity as i have set up mappings in module initilize.
          public CustomerDetailsViewViewModel(ICustomerDetailsView view)
              :base(view)
          {
          }
    
           public string Message
           {
              //INotifyPropertyChanged left out for brevity
              get;set;
           }
       }
    

    I have a few questions.

    1.)Isnt this violation of MVVM as code behind file is supposed to have zero code?

    2.)in MVVM view model should not worry the view or its contract?Doesnt the above implementation break it?

    3.)I cannot understand what is the use of this implementation. In fact this borders on MVP and lot of code is required.

    4.)If this is an acceptable way to implement, do i need to have interfaces for all the views and viewmodels in all of my modules.?

  • Gone Coding
    Gone Coding almost 12 years
    Spot on. ViewModels are dumb containers that have no concept of what is viewing them. I strongly recommend introducing controllers into MVVM to ensure this sort of situation is not required. @Peter Ritchie: VMs should not be controllers... that is a fundamental flaw on the way MVVM examples are propagated. Roll on MVCVM! :)