I'm familiar with MVC but I'm trying to learn WPF with Ninject. Can some one give me some example or reference?
As I said in my comment to your OP, all the information you require is available within the Ninject documentation. That said it could be argued that it is easy to get lost within its vast documentation if you are unfamiliar with Ninject and/or DI.
There are a few tutorials online of which this one I thought was particularly informative. Whilst it provides an example using a console application
, the principles of how Ninject
works remain the same.
Irrespective of your application type you configure your container at your application entry point;
- Console app -
Main
- WPF -
App
(unless you are using a framework in which case you may provide a custom bootstrapper) - ASP.NET - No idea, perhaps someone could enlighten me
DISCLAIMER I do not claim to be an authority on Ninject
or DI
, below is simply a quick example of how I understand these two objects can be used in conjunction with one another.
For example sake, let us work with the examples provided in the Ninject documentation.
1) Create a WPF application named NinjectIoC
2) Use Nuget to add a reference to the Ninject
project
3) Open App.xaml
and remove the StartupUri
property from the Application
element so that your App.xaml
looks like below:
<Application x:Class="NinjectIoC.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Application.Resources>
</Application.Resources>
</Application>
The reason we do this is because the StartupUri
property informs the WPF
application which UI control to initially display when the application starts. We are going to use Ninject
to display our initial UI control.
4) Open App.xaml.cs
. This is where we are going to configure the Ninject
container
, or Kernel
to use Ninject
terminology. We override
the application OnStartup
method so that we may configure our container
and subsequently initialise the application as we would like. Update the content of your App.xaml.cs
to look as follows:
namespace NinjectIoC
{
using Ninject;
using System.Windows;
public partial class App
{
private IKernel container;
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
ConfigureContainer();
ComposeObjects();
Current.MainWindow.Show();
}
private void ConfigureContainer()
{
this.container = new StandardKernel();
container.Bind<IWeapon>().To<Sword>().InTransientScope();
}
private void ComposeObjects()
{
Current.MainWindow = this.container.Get<MainWindow>();
Current.MainWindow.Title = "DI with Ninject";
}
}
}
A brief explination:
4.1) OnStartup - Override the
OnStartupmethod so that we may configure our
container` and initialise the application as we desire.
4.2) ConfigureContainer
- Inform our container
of how we would like to resolve our concrete types. There is far more to this than I have displayed in this example, however, there is far more to this than I have shown. There are topics such as Multi Binding, Binding Conventions and Kernel Modules for which you are best learning about it from the official documentation.
4.3) ComposeObjects
- Having removed the StartupUri
property from App.xaml
we must inform the application which UI control we would like it to use for the MainWindow
. Alongside asking our container
to use MainWindow
as our MainWindow
we set the Title
property too. Again you might want to do other tasks here for manual object composition.
You do not have to separate out the steps as I have above, for this contrived example it would make more sense not to bother. As your application grows and you start to do more sophisticated things with the container
, separating some of the stages out begins to make the container
configuration more manageable. The choice is yours.
5) Next open MainWindow.xaml
, then copy and paste the following:
<Window x:Class="NinjectIoC.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="78" Width="362">
<Grid>
<Button Content="Button" HorizontalAlignment="Left" Margin="269,10,0,0" VerticalAlignment="Top" Width="75" Click="Attack"/>
<TextBox x:Name="Target" HorizontalAlignment="Left" Height="23" Margin="10,10,0,0" VerticalAlignment="Top" Width="254"/>
</Grid>
</Window>
I shall not bother explaining the above as it should be obvious what is going on.
6) Finally open MainWindow.xaml.cs
and update it as follows:
namespace NinjectIoC
{
using System.Windows;
public partial class MainWindow
{
private readonly IWeapon weapon;
public MainWindow(IWeapon weapon)
{
this.weapon = weapon;
InitializeComponent();
}
private void Attack(object sender, RoutedEventArgs e)
{
this.weapon.Hit(this.Target.Text);
}
}
public class Sword : IWeapon
{
public void Hit(string target)
{
MessageBox.Show(@"I swing and thrust my sword about like a mad man at " + target);
}
}
public interface IWeapon
{
void Hit(string target);
}
}
Again I will make this brief as what is happening above has nothing to do with the configuration of Ninject
and it should once again be obvious what is happening.
The main thing to notice in the above is the argument
that the MainWindow
constructor expects; IWeapon
. You might be asking yourself How does that get resolved as I am not creating a concrete implementation of Weapon
anywhere?
Well during the ConfigureContainer
method in App.xaml.cs
we informed the container
how we would like it to resolve dependencies for IWeapon
:
container.Bind<IWeapon>().To<Sword>().InTransientScope();
The above tells the container
that anywhere it encounters a dependency for IWeapon
we would like it to provide an instance of Weapon
. Upon requesting the container
resolve (Get
) our initial MainWindow
control, using the following:
Current.MainWindow = this.container.Get<MainWindow>();
The container
took a look at its constructors and determined the constructor with the most arguments it understood. In this example it was the constructor that required an implementation of IWeapon
and oh look, the container
knows how to resolve this dependency because we told it how to do so earlier in ConfigureContainer
.
Assuming neither you nor I have made any mistakes with the above code, pressing F5
should launch the application and you should see a small window with a TextBox
and Button
. Enter something in to the TextBox
then press the Button
and you should see a MessageBox
control informing you that you swang your sword like a "mad man"
at whoever or whatever you entered in the TextBox
.
There is far more to both Ninject
and DI
than I have described here. For example there are entire books on the subject of DI
such as this one by Mark Seeman.
Hopefully the above will give you at basic starting point of where to look and where to go to progress further with your adventures with Ninject
and DI
.
© 2022 - 2024 — McMap. All rights reserved.