a·gen·tic a·gil·i·ty

Wpf Ninject Dojo: The Data Provider

Explains how to use a custom NinjectDataProvider in WPF to enable dependency injection for ViewModels, improving flexibility and design-time support in MVVM projects.

Published on
4 minute read
Image
https://nkdagility.com/resources/fiHZn7VEOpq
Subscribe

You have probably heard me go on about Unity a couple of times:

I have been using what is now unity since the good old days (sooo not true, WPF is the Windows Forms killer, and good riddance) of WindowsForms and CAB (Client Application Block), but now there is a lightweight alternative: Ninject .

I decided on my latest project (a Wpf dashboard for HEAT ITSM) that I needed dependency injection. Whenever I start building a MVVM project I always end up needing some sort of dependency injection to keep everything nice and neat. It is only really needed once you get to a certain size and when you start wanting talk between ViewModels .

Anyway I was using a method of injecting my ViewModels into the Views using standard binding:

 1<igDock:ContentPane x:Class="SlaTodayView"
 2    xmlns:igDP="http://infragistics.com/DataPresenter"
 3    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 4    xmlns:local="clr-namespace:WpfHeatItsmDashboard"
 5    xmlns:igWindows="http://infragistics.com/Windows"
 6    xmlns:igDock="http://infragistics.com/DockManager"
 7    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 8    Header="Sla Today" MinWidth="30" MinHeight="50">
 9    <igDock:ContentPane.Resources>
10        <ObjectDataProvider
11        x:Key="ViewModel"
12        ObjectType="{x:Type local:SlaTodayViewModel}"
13        />
14    </igDock:ContentPane.Resources>
15    <igDP:XamDataGrid DataContext="{StaticResource ViewModel}" DataSource="{Binding Calls}" Theme="Office2k7Black" >
16
17    </igDP:XamDataGrid>
18</igDock:ContentPane>

But once you move to dependency injection you do not want to keep all those fixed object definitions. These may become interfaces, or you may just want to replace, or dynamically replace, one of these types by a derived one at runtime.

That being the goal, we need some way to retrieve that type even in design mode. There is nothing worse than components or bits of components that make it difficult to work in both Visual Studio and Blend, and with the new binding features of Visual Studio 2010 for WPF 4 it will be even more important that your usage is as compatible as possible.

What I decided to do was create a custom DataSourceProvider, called the NinjectDataProvider that I could use instead of the ObjectDataProvider. This is the first version of that provider and it does nothing more than retrieve the type form the Ninject Kernel. Minimal changes to the WPF enable this:

 1<igDock:ContentPane x:Class="SlaTodayView"
 2    xmlns:igDP="http://infragistics.com/DataPresenter"
 3    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 4    xmlns:local="clr-namespace:WpfHeatItsmDashboard"
 5    xmlns:igWindows="http://infragistics.com/Windows"
 6    xmlns:igDock="http://infragistics.com/DockManager"
 7    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 8    Header="Sla Today" MinWidth="30" MinHeight="50">
 9    <igDock:ContentPane.Resources>
10        <local:NinjectDataProvider
11        x:Key="ViewModel"
12        ObjectType="{x:Type local:SlaTodayViewModel}"
13        />
14    </igDock:ContentPane.Resources>
15    <igDP:XamDataGrid DataContext="{StaticResource ViewModel}" DataSource="{Binding Calls}" Theme="Office2k7Black" >
16
17    </igDP:XamDataGrid>
18</igDock:ContentPane>

As you can see, the only difference is highlighted above and shows the custom DataSourceProvider in action.

Wpf Ninject Dojo: The Data Provider   You can see from the image above that the designer capability is not affected with this actually loading from the database, nice!

So, what do we need to do to achieve this marvellous result. its actialy fairly simple, I got out my trusty reflector and found that there is really only one method to override.

 1Imports System.ComponentModel
 2Imports System.Threading
 3
 4Public Class NinjectDataProvider
 5    Inherits DataSourceProvider
 6
 7    Private m_objectType As Type
 8
 9    Public Property ObjectType() As Type
10        Get
11            Return Me.m_objectType
12        End Get
13        Set(ByVal value As Type)
14            If Not m_objectType Is value Then
15                m_objectType = value
16                Me.OnPropertyChanged("ObjectType")
17                If Not MyBase.IsRefreshDeferred Then
18                    MyBase.Refresh()
19                End If
20            End If
21        End Set
22    End Property
23
24    Private Overloads Sub OnPropertyChanged(ByVal propertyName As String)
25        MyBase.OnPropertyChanged(New PropertyChangedEventArgs(propertyName))
26    End Sub
27
28    Protected Overrides Sub BeginQuery()
29        If m_objectType Is Nothing Then
30            Me.OnQueryFinished(Nothing, New InvalidOperationException("You must provide an ObjectType"), Nothing, Nothing)
31        End If
32        Dim result As Object
33        Try
34            result = Application.NinjectKernel.Get(m_objectType)
35            Me.OnQueryFinished(result, Nothing, Nothing, Nothing)
36        Catch ex As Exception
37            Me.OnQueryFinished(Nothing, ex, Nothing, Nothing)
38        End Try
39    End Sub
40
41End Class

I do not yet need all the fancy features of Ninject yet so I have only implemented the bit that I need at the moment. If I am adding more (and get it working) I will blog about it in the future.

To get this working I needed to add an instance of an IKernel object to the “Application” file so I have a single Kernel instance through my application unless I want another, but this is a small price to pay and it could well have been done in the same way as the My.Unity.Resolve(Of Ninja) post I did on Unity .

Start your Ninja training today!

Technorati Tags: .NET   CodeProject   MVVM   WPF   VS 2010

Software Development Technical Mastery
Subscribe

Related Blog

No related videos found.

Connect with Martin Hinshelwood

If you've made it this far, it's worth connecting with our principal consultant and coach, Martin Hinshelwood, for a 30-minute 'ask me anything' call.

Our Happy Clients​

We partner with businesses across diverse industries, including finance, insurance, healthcare, pharmaceuticals, technology, engineering, transportation, hospitality, entertainment, legal, government, and military sectors.​

Slicedbread Logo

Slicedbread

Microsoft Logo

Microsoft

Jack Links Logo

Jack Links

DFDS Logo

DFDS

Freadom Logo

Freadom

Big Data for Humans Logo

Big Data for Humans

Philips Logo

Philips

Higher Education Statistics Agency Logo

Higher Education Statistics Agency

Brandes Investment Partners L.P. Logo

Brandes Investment Partners L.P.

Epic Games Logo

Epic Games

Teleplan Logo

Teleplan

YearUp.org Logo

YearUp.org

ALS Life Sciences Logo

ALS Life Sciences

Schlumberger Logo

Schlumberger

Healthgrades Logo

Healthgrades

Kongsberg Maritime Logo

Kongsberg Maritime

Slaughter and May Logo

Slaughter and May

Akaditi Logo

Akaditi

Department of Work and Pensions (UK) Logo

Department of Work and Pensions (UK)

Washington Department of Transport Logo

Washington Department of Transport

Nottingham County Council Logo

Nottingham County Council

New Hampshire Supreme Court Logo

New Hampshire Supreme Court

Ghana Police Service Logo

Ghana Police Service

Washington Department of Enterprise Services Logo

Washington Department of Enterprise Services

Healthgrades Logo

Healthgrades

Milliman Logo

Milliman

New Signature Logo

New Signature

Flowmaster (a Mentor Graphics Company) Logo

Flowmaster (a Mentor Graphics Company)

Lockheed Martin Logo

Lockheed Martin

Microsoft Logo

Microsoft