Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ninject constructor injection in WPF

Tags:

c#

wpf

ninject

Is it possible to use ninject for dependency injection in such a way that the result would be something like the injection I can get in MVC. To elaborate, if I use the MVC ninject adapter I can declare my web controllers as having constructor parameters which would then automatically be injected by ninject.

However, I haven't found such a ninject extension for WPF, which would enable me to have a window such as this:

public partial class MainWindow : Window
{
    private readonly IService injectedService;
    public MainWindow(IService injectedService) 
    {
        this.injectedService = injectedService;
    }
}

I would like to do this without explicitly using the IKernel in my main application startup to obtain an instance of mainwindow. I'd much prefer to use the normal method of xaml configuration to obtain an instance of the main window and all subsequent windows.

Is this possible? Is there any way to hook into the object creation generated by xaml to modify it to use Ninject for constructor dependency injection.

like image 637
Dervall Avatar asked Feb 06 '12 12:02

Dervall


1 Answers

Based on the comments & your confusion, it looks like MVVM is a good match for you. The challenge is, LEARNING MVVM.

So crack open a good link and get rolling. MVVM is surprisingly easy to do, and it's pretty easy to wrap it all up with Ninject and put a bow on it.

The initial learning curve if you DON'T use a 3rd party library for Ninject + MVVM like I did, is a bit steep. So here's a couple of things I had to understand:

        DataContext="{Binding Path=ResultViewModel,Source={StaticResource ServiceLocator}}"

This little addition makes allows you to trigger ninject to get your viewmodel information from your XAML:

<Application.Resources>
    <ioc:NinjectServiceLocator x:Key="ServiceLocator" />
</Application.Resources>

this little trick allows you to assign that staticresource from your app.xaml file to the relevant class

public class NinjectServiceLocator
{
    private readonly IKernel kernel;

    public NinjectServiceLocator()
    {
        kernel = new StandardKernel(new MyMvvmModule());
    }

    public ResultViewModel ResultViewModel
    {
        get { return kernel.Get<ResultViewModel>(); }
    }
}

This is notable. Every viewmodel must be listed as a property in the ServiceLocator in order for Ninject to generate them. Finally, MyMvvmModule in the example above is the standard Ninject class where you stick your override for Load() and bind all your interfaces.

like image 111
deltree Avatar answered Sep 23 '22 09:09

deltree