Deprecated data in MVVM ViewModels with dependency injection

In my WPF application, I use the MVVM pattern along with dependency injection.

ViewModels, which prepare data from the database, get the repository entered into the constructor. They also populate properties with data from the repository in the constructor.

ViewModels are created in the static constructor of the ViewModelLocator class, which all views use to bind to their ViewModel.

This has the following disadvantages:

  • Data in views is never updated, even if it is closed and reopened, because the ViewModel instance is always the same.
  • When you open the first view, all instances of ViewModels are created and the data they require is loaded from the database.

I can think of two ways to solve these problems:

  • Make each ViewModel an implemented method that reads data from the database and initializes the properties - instead, in the constructor. This would require calling this method each time the view is opened. This introduces a temporary connection that I don't like.
  • Deploy the ViewModelLocator so that it creates the requested ViewModel each time the corresponding property in the ViewModelLocator is called. I do not like this method because my root structure will not be executed when the program starts, but will be distributed throughout the life cycle of the program instance.

Is there any other way to solve this problem? How do others solve this?

+5
source share
2 answers

ViewModelLocator , ViewModel , ViewModelLocator.

, . ViewModelLocator, DI ViewModels, , ViewModel.

, , .

"", , , . , ViewModel.

, MEF, , ExportFactory<T> . NonShared Creation Policy ViewModels .

+2

ViewModelBase RefreshDataCore(). , Refresh() ViewModel IsDirty. ViewModel.IsVisible IsDirty , Refresh() .

, , viewmodels , , Refresh().

An example is below. (I left INPC notifications for simplicity)

public abstract class ViewModelBase
{
     //Pull your data from the repository here
     protected abstract void RefreshCore();
     public void Refresh()
     {
            RefreshCore();
            IsDirty = false;
     }

     private bool _isVisible = false;
     //DataBind this to the visibility of element "hosting" your view model
     public bool IsVisible
     {
         get { return _isVisible; }
         set
         {
              if (_isVisible == value)
                  return;


              _isVisible = value;
              if (IsVisible && IsDirty)
                   Refresh();
         }
     }

     private bool _isDirty = true;
     public bool IsDirty 
     {
         get { return _isDirty; }
         set 
         {
            if (_isDirty == value)
               return;

            _isDirty = value;
            if (IsVisible && IsDirty)
               Refresh();
         }
     }

}
0
source

All Articles