Home > C#, MVVM, Universal Windows Platform > Using IoC and Design time support with MVVM Light and Template 10

Using IoC and Design time support with MVVM Light and Template 10

23/09/2015

In the last post we talked about Integrating Template10 with MVVM Light. Now let’s see how to use some basic services provided by MVVM Light, starting with SimpleIoC and Design time support.

In the previous post we already used it to register a simple ViewModel, but it is more powerful, and for example we can leverage it to inject dependencies. For example, let’s define the following service:

public interface IDataService
{
    IEnumerable<Person> GetPeople();
}

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

public class DesignTimeDataService : IDataService
{
    public IEnumerable<Person> GetPeople()
    {
        var people = from n in Enumerable.Range(1, 100)
                     select new Person
                     {
                         FirstName = "Design Time First Name " + n,
                         LastName = "Design Time Last Name " + n
                     };

        return people;
    }
}

public class RuntimeDataService : IDataService
{
    public IEnumerable<Person> GetPeople()
    {
        var people = new List<Person>();

        // In a real scenario, these people are retrived for example via 
        // a Web API.
        people.Add(new Person { FirstName = "Donald", LastName = "Duck" });
        people.Add(new Person { FirstName = "Mickey", LastName = "Mouse" });
        people.Add(new Person { FirstName = "Daisy", LastName = "Duck" });

        return people;
    }
}

The IDataService interface defines a method the retrieves a list of people. Then we have a design and a runtime implementation. We need to register them in the ViewModelLocator class:

public class ViewModelLocator
{
    static ViewModelLocator()
    {
        ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
 
        if (GalaSoft.MvvmLight.ViewModelBase.IsInDesignModeStatic)
        {
            // We are at design time.
            SimpleIoc.Default.Register<IDataService, DesignTimeDataService>();
        }
        else
        {
            // We are at runtime.
            SimpleIoc.Default.Register<IDataService, RuntimeDataService>();
        }
 
        SimpleIoc.Default.Register<MainViewModel>();
    }
 
    // ...
}

At line 7 we use the MVVM Light ViewModelBase.IsInDesignModeStatic property to check if we are at design time (in fact, since the ViewModelLocator is declared as a resource in the App.xaml file, it is automatically instantiated, even if the app isn’t explicitly executed). If so, we register in the MVVM Light SimpleIoC container the type DesignTimeDataService for the interface IDataService. Otherwise, if we are at execution time we register the type RuntimeDataService.

Now we can pass an object implementing the IDataService interface to our View Model:

public class MainViewModel : Template10.Mvvm.ViewModelBase
{
    private IEnumerable<Person> people;
    public IEnumerable<Person> People
    {
        get { return people; }
        set { this.Set(ref people, value); }
    }

    private readonly IDataService dataService;

    public MainViewModel(IDataService dataService)
    {
        this.dataService = dataService;

        if (GalaSoft.MvvmLight.ViewModelBase.IsInDesignModeStatic)
        {
            // Loads people to enable desgin time support.
            People = dataService.GetPeople();
        }
    }

    public override void OnNavigatedTo(object parameter, NavigationMode mode, 
        IDictionary<string, object> state)
    {
        // Loads real data.
        People = dataService.GetPeople();

        base.OnNavigatedTo(parameter, mode, state);
    }
}

In this way, when we are at design time, the type passed to MainViewModel is DesignTimeDataService, while at execution time we’ll have a RuntimeDataService. In fact, in the MainViewModel constructor (lines 12-20) we check whether we are actually at design time, and so we call the GetPeople method, in order to show dummy data (from DesignTimeDataService) to enable design time support. Note that we again use a method available in the ViewModelBase class that comes from MVVM Light, and not the Template10 ViewModelBase implementation from which the View model inherits:

Design Time data

Design Time data

Finally, in the Template 10 OnNavigatedTo method (lines 23-30), we call again GetPeople: as this method is executed when we are at runtime, now we’re retrieving information from RuntimeDataService:

Runtime data

Runtime data

Working with interfaces and implementations is strongly recommended. Besides allowing design time support, as we have just seen, it make easier to test our code. MVVM Light provides all the tools that we need to do that (like a simple IoC container), and integrating it in a project built with Template 10 is straightforward.

You can download the complete example using the link below:
Using IoC with MVVM Light and Template10

  1. 16/10/2015 at 15:06

    Using OnNavigatedTo or bind a command on page load event, for instance, could have the same behavior, in this case?

    • 16/10/2015 at 15:08

      The OnNavigatedTo method is called only at application run, not at design time, so if you use this method, you can’t achieve the same result as described in the post.

  1. 23/09/2015 at 13:03
Comments are closed.
%d bloggers like this: