Tuesday, January 18, 2011

Simple Dependency Injection with XAML

Let’s start by painting a simple scenario:  I have a ViewModel that lists a collection of data items.  Let’s say a list of Tweets based on a given hash tag search.  The ViewModel has a SaveCommand that I will wire into my view.  When the user causes the SaveCommand to execute, the ViewModel will leverage some service to persist the selected tweet to some form of storage.  And there is the rub…  Maybe in v1, I will save that tweet in IsolatedStorage, but in the future, I will want to also provide an option to select a cloud-based storage solution.  This is is where we start to hear all kind of things about Dependency Injection, IoC, and more.

Hey, I am a fan of Dependency Injection and using in IoC container, but the what I hate about DI/IoC is that is takes me away from the pure XAML-based goodness of defining my ViewModel in XAML view an element’s DataContext and into the world of code-behind and setting things up with code. I would much rather do this in MainPage.xaml

<UserControl.DataContext>
    <nScreenLibrary_ViewModels:SearchViewModel/>
</UserControl.DataContext>

than have to start resorting to this in my MainPage.xaml.cs code-behind file…

this.DataContext = new SearchViewModel();

Obviously this is a simple example that does not use DI or an IoC.  Things would be much more complicated as I would need to configure the IoC, call into the IoC to get the correct instance of a ViewModel, and then assign that to my DataContext. I would really like to be able to stick to a XAML-based solution for configuring my application to use different storage providers without having to resort to using code-behind, picking an IoC, etc.  While the DI/IoC route may be needed for complex scenarios, a lot of applications only need a simple solution.

That brings us to using XAML to accomplish a version of Property-based Dependency Injection.  By no means am I saying this solution is perfect.  But I think it will work for a lot of people.  There really is no rocket science here, but if you are still new to XAML and haven’t explored a lot of its power, this may prove a useful solution.  In addition, as I searched around the Intertubes for a similar approach, I couldn’t find one which means I am either blazing a trail that will prove beneficial to many, or I am so far off the reservation that the Developer Police will be coming to take me away shortly.

That brings us to the solution.  Supposed I have a ViewModel that looks something like this

   public class SearchViewModel :BaseViewModel
   {
       public ObservableCollection<MyDataItem> SearchItems{ get; set; }
       public RelayCommand SaveCommand { get; set; }
       private IFavoritesService _favs;
       public SearchViewModel() : base()
       {
           this.Tweets = new ObservableCollection<Tweet>();    
     
           this.SaveCommand = new RelayCommand()
           {
               CanExecuteCommand = (tweet) => {
                   var saveTweet = tweet as Tweet;

Read more: SlickThought.Net