简体   繁体   中英

Best practice to design an application that needs a BackgroundAgent using MVVM pattern

While the title may seem too broad, I actually have not found any hint on how to solve this problem.


EDIT: While I tagged the question properly, I forgot to write that I'm using Caliburn.Micro and this means that I must have both Views and ViewModels in the same project, and this forces me to have a separate library project for the Model , as the Background Agent can't depend on the app's project


Before diving into the question, here's a little example of the situation:

- App Solution
\- Model (C# library)
\- Background agent
\- Real App
  \- Views
  \- ViewModels
  \- Resources and other stuff

where Real App and Background Agent depend on Model .

This seems to me the easiest way to make things work in my scenario.

The problem comes when I need to work with binding. In my previous projects I used to merge the Model and the ViewModel classes into one so that I could just bind the XAML to the VIewModel 's properties without any kind of problem.

But now, since I'm forced to keep my Model in a separate project (the Background Agent can't depend on Real App ), I have no idea on how this should work.

To make things more complex, my Model uses the async pattern to load data.

And this leads to the first question: since the Model loads data using th async pattern, how can I notify to the ViewModel that the data is ready to be displayed?

To make the question clearer, here's a quick snippet about this question:

namespace Models
{
    public class Model
    {
        private string _neededProperty;
        public string NeededProperty
        {
            get
            {
                return _neededProperty;
            }
            set
            {
                if (value == _neededProperty) return;
                _neededProperty = value;
                OnPropertyChanged();
            }
        }

        public Model()
        {
            LoadData();
        }

        private async void LoadData()
        {
            NeededProperty = await StuffLoader();
        }

        private Task<string> StuffLoader()
        {
            return LoadStringAsync();
        }
    }
}

namespace ViewModels
{
    public class ViewModel
    {       
        public string NeededProperty
        {
            get
            {
                // Let's assume that we have a global instance of our model defined in the App.xaml.cs file
                return App.Model.NeededProperty;
            }
        }
    }
}

// Page.xaml
...
    <TextBlock Text="{Binding NeededProperty, Source={StaticResource ViewModel}}"/>
...

How can I be sure that the TextBlock loads fine once the Model has loaded the string?

Of course the same problem needs to be solved to make the Background Agent work, because it relies on the same loading methods of the Model .

So, basically, the question is: provided that my structure is correct and that this is the best way to organize the project, how can I "listen" on Model 's properties to report each change to the ViewModel and the Background Agent ?

This could be also useful to show some kind of loading screen, which has to be shown in the Real App part and so I need to know when the Model actually finishes its loading routines.

I hope that the question is clear, I'm a little bit confused now because this requires a big paradigm shift when coming from Java!

ViewModel should not be in the same project as Views. That way you can re-use Model and ViewModel in a different App if needed (ex: desktop and phone app). Therefore, I would use your background agent in the viewmodel (maybe through the model depending on what your are doing exactly). That way the background agent is not known from the app and your app is using your ViewModel the same way as with or without the ViewModel

IMO that is the cleanest and easiest way.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM