Morse Coder Part 4 : Dependency Injection with MVVM Light SimpleIoc

To date, we have a functional, but basic set of Windows Phone and Windows Store applications which can translate Alphabetical Input to Morse Code. One of the key tenets of MVVM Light is the ability to inject design time services or functionality to provide a better design experience. We need somewhere to store our Application Settings, along with a means of setting and retrieving them, we won’t cover the implementation of this, but we will cover the creation of our interface and the implementation of a design time settings class.

Outcome

By the end of this post we will have, at design time, the ability to manipulate a settings class to be used with the designer in Visual Studio, or through Expression Blend. This will be done via an application settings interface detailing what data we need to store and of course what type it needs to be. As we are targeting multiple platforms, the interface, in a future post will be implemented to provide the storage of our settings per operating system.

One of the main benefits of using Dependency Injection to achieve this is that the implementation of our ViewModel is not concerned with where it retrieves information from and doesn’t need to make decisions depending on which context it is being ran in, this moves us closer to alignment with the Single Responsibility Principle.

Prerequisites

Implementation

We’ll keep it minimal for now and only define a couple of Properties. We know that we want to store our user’s last input as a string, and their translation direction in order to set up our Translator and User Interface as covered in Morse Coder Part 3. We can create an enum type to store our Translation Direction, simply :

public enum TranslationDirection
{
MorseToAlphabet,
AlphabetToMorse,
}[/csharp]

We can now create our interface as follows:

[csharp]namespace MorseCoder.Interfaces
{
public interface IMorseCoderSettings
{
string Input {get;set; }
TranslationDirection Direction {get;set; }
}
}

Note the definition of the get and set accessors on our interface, this is the behaviour we’re defining. We want to be able to get and set a string Input Property, and a TransaltionDirection Direction Property.
We can now implement this interface on a DesignMorseCoderSettings class :

namespace MorseCoder.Design
{
public class DesignMorseCoderSettings : IMorseCoderSettings
{
public string Input
{
get
{
return "Design Morse Coder Input Setting";
}
set
{
throw new NotImplementedException();
}
}

public TranslationDirection Direction
{
get
{
return TranslationDirection.AlphabetToMorse;
}
set
{
throw new NotImplementedException();
}
}
}
}

Again, note the get and set accessors, we aren’t interested in ‘setting’ at Design Time at the moment so we needn’t worry about them, but we can return some content to our Input string and a default TranslationDirection.

We’ve created our interface and an implementation, it’s now time to register these with our Inversion of Control (IoC) container. In Morse Coder Part 1 we covered the creation of a ViewModelLocator Class with a static ViewModelLocator method to register our container (SimpleIoc) and our MainViewModel; we’ll be adding to this in order to register our DesignMorseCoderSettings Class based in which context we are currently running in.

static ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
SimpleIoc.Default.Register<MainViewModel>();

if (ViewModelBase.IsInDesignModeStatic)
{
SimpleIoc.Default.Register<IMorseCoderSettings, DesignMorseCoderSettings>();
}
else
{
// not design mode, set up Proper Morse Coder Settings
}
}

As you can see, if we are in design mode, we register our DesignMorseCoderSettings, or put simply: when our application asks for an instance of IMorseCoderSettings it will get a cached copy of our DesignMorseCoderSettings. We can now do exactly that, SimpleIoc will inject dependencies into our constructor when we instantiate our View Model, so we’ll need to update our MainViewModel constructor to include our new IMorseCoderSettings interface.

Considerations :

  • Constructor will need to be updated to add the new interface;
  • We’ll need to store the implementation provided by the constructor in a private field;
  • The Input Property can now come from our settings;
  • We now know which TranslationDirection we want to use, so can make decisions accordingly.
namespace MorseCoder.ViewModel
{
public class MainViewModel : ViewModelBase
{
private ITranslator _translator;
private IMorseCoderSettings _morseCoderSettings;

...

private TranslationDirection _direction;

...

public MainViewModel(IMorseCoderSettings morseCoderSettings)
{
_morseCoderSettings = morseCoderSettings;

_input = _morseCoderSettings.Input;
_direction = morseCoderSettings.Direction;

switch (_direction)
{
case TranslationDirection.AlphabetToMorse:
_translator = new AlphabetToMorseTranslator();
BackgroundBrush = new SolidColorBrush(Colors.CadetBlue);
break;
case TranslationDirection.MorseToAlphabet:
_translator = new MorseToAlphabetTranslator();
BackgroundBrush = new SolidColorBrush(Colors.Crimson);
break;
}

Translation = _translator.Translate(Input);
}
}
}

Note the inclusion of the new interface on the constructor. As mentioned, we’ve ‘requested’ an implementation of IMorseCoderSettings, and SimpleIoc will take care of returning one, in this case DesignMorseCoderSettings. We’ve set our private IMorseCoderSettings up with the implementation received and can then use it to ‘get’ our settings and set up our ITranslator interface and user interface based on which direction we want to translate.

So without making any changes to our View’s data binding, we’ve provided some more meaningful information into our ViewModel so our designer for Windows Phone should now look like this…

Windows Phone Designer with Dependency Injection
Windows Phone Designer with Dependency Injection

…and at run time for Windows…

Windows Run Time with Dependency Injection
Windows Run Time with Dependency Injection

Summary

Where are we?

  • We’ve laid the groundwork for our platform specific application settings classes using Dependency Injection and created a design time settings class along the way.

Where are we heading?

  • The next in the series will cover a few Unit Tests to ensure that the translations we’re getting out of the Translator Classes are what we would expect to see.

 

3 thoughts on “Morse Coder Part 4 : Dependency Injection with MVVM Light SimpleIoc”

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s