我熟悉MVC,但我正在尝试使用Ninject学习WPF。有人可以给我一些例子或参考吗?
答案 0 :(得分:61)
正如我在您对您的OP的评论中所述,您需要的所有信息都在Ninject documentation内。也就是说,如果你不熟悉Ninject和/或DI,很可能会在其庞大的文档中迷失。
网上有一些教程this one我认为这些教程特别有用。虽然它提供了使用console application
的示例,但Ninject
的工作原理保持不变。
无论您的应用程序类型如何,都要在应用程序入口点配置容器;
Main
App
(除非您使用的是框架,在这种情况下您可以提供自定义引导程序) 免责声明我并不声称自己是Ninject
或DI
的权威,下面只是一个快速举例说明我如何理解这两个对象可以< / em>彼此结合使用。
例如,让我们使用Ninject文档中提供的示例。
1)创建名为NinjectIoC
2)使用Nuget添加对Ninject
项目的引用
3)打开App.xaml
并从StartupUri
元素中移除Application
属性,以便您的App.xaml
如下所示:
<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>
我们这样做的原因是因为StartupUri
属性通知WPF
应用程序在应用程序启动时最初显示哪个UI控件。我们将使用Ninject
来显示我们的初始UI控件。
4)打开App.xaml.cs
。这是我们要配置Ninject
container
或Kernel
以使用Ninject
术语的地方。我们override
应用OnStartup
方法,以便我们可以配置我们的container
,然后根据需要初始化应用程序。更新App.xaml.cs
的内容,如下所示:
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";
}
}
}
简短的探索:
4.1) OnStartup - Override the
OnStartup method so that we may configure our
container`并根据需要初始化应用程序。
4.2) ConfigureContainer
- 告知我们container
我们希望如何解决具体类型。除了我在这个例子中展示的内容远不止这些,但是,这比我所展示的要多得多。有Multi Binding,Binding Conventions和Kernel Modules等主题,您最好从official documentation了解这些主题。
4.3) ComposeObjects
- 从StartupUri
删除了App.xaml
属性后,我们必须通知应用程序我们希望它用于哪个UI控件{ {1}}。除了要求我们MainWindow
使用container
作为我们的MainWindow
之外,我们也设置了MainWindow
属性。同样,您可能希望在此处执行其他任务以进行手动对象组合。
你不必像上面那样分离出这些步骤,对于这个人为的例子来说,更加有意义的是不要打扰。随着应用程序的增长,您开始使用Title
执行更复杂的操作,将一些阶段分开开始使container
配置更易于管理。选择是你的。
5)接下来打开container
,然后复制并粘贴以下内容:
MainWindow.xaml
我不打算解释上面的内容,因为它应该是显而易见的。
6)最后打开<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>
并按如下所示进行更新:
MainWindow.xaml.cs
我再次简要介绍一下,因为上面发生的事情与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);
}
}
的配置无关,而且应该再一次明白发生了什么。
上面要注意的主要问题是Ninject
构造函数所期望的argument
; MainWindow
。您可能会问自己如何解决这个问题,因为我没有在任何地方创建IWeapon
的具体实现?
在Weapon
的{{1}}方法中,我们通知ConfigureContainer
我们希望如何解决App.xaml.cs
的依赖关系:
container
上面告诉IWeapon
,遇到container.Bind<IWeapon>().To<Sword>().InTransientScope();
的依赖关系时,我们希望它提供container
的实例。在使用以下内容请求IWeapon
解析(Weapon
)我们的初始container
控件后:
Get
MainWindow
查看了它的构造函数,并确定了构造函数,它理解的参数最多。在这个例子中,构造函数需要Current.MainWindow = this.container.Get<MainWindow>();
的实现哦看看,container
知道如何解决这种依赖关系,因为我们告诉它如何在IWeapon
中更早地这样做。 / p>
假设您和我都没有犯过上述代码的任何错误,请按container
启动应用程序,您应该会看到一个包含ConfigureContainer
和F5
的小窗口。在TextBox
输入内容,然后按下Button
,你会看到一个TextBox
控制按钮,通知你,无论你输入的是谁,你都会像Button
那样挥剑。 MessageBox
。
"mad man"
和TextBox
比我在此描述的要多得多。例如,有Ninject
主题的整本书籍,例如this one by Mark Seeman。
希望上述内容能够让您从DI
和DI
开始进一步了解您的冒险活动的基本起点以及在哪里进一步发展。