如何在WPF应用程序中使用Ninject

时间:2013-12-16 15:54:01

标签: wpf ninject

我熟悉MVC,但我正在尝试使用Ninject学习WPF。有人可以给我一些例子或参考吗?

1 个答案:

答案 0 :(得分:61)

正如我在您对您的OP的评论中所述,您需要的所有信息都在Ninject documentation内。也就是说,如果你不熟悉Ninject和/或DI,很可能会在其庞大的文档中迷失。

网上有一些教程this one我认为这些教程特别有用。虽然它提供了使用console application的示例,但Ninject的工作原理保持不变。

无论您的应用程序类型如何,都要在应用程序入口点配置容器;

  • 控制台应用 - Main
  • WPF - App(除非您使用的是框架,在这种情况下您可以提供自定义引导程序)
  • ASP.NET - 不知道,也许有人可以启发我

免责声明我并不声称自己是NinjectDI的权威,下面只是一个快速举例说明我如何理解这两个对象可以< / em>彼此结合使用。

例如,让我们使用Ninject文档中提供的示例。

1)创建名为NinjectIoC

的WPF应用程序

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 containerKernel以使用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 BindingBinding ConventionsKernel 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启动应用程序,您应该会看到一个包含ConfigureContainerF5的小窗口。在TextBox输入内容,然后按下Button,你会看到一个TextBox控制按钮,通知你,无论你输入的是谁,你都会像Button那样挥剑。 MessageBox


"mad man"TextBox比我在此描述的要多得多。例如,有Ninject主题的整本书籍,例如this one by Mark Seeman

希望上述内容能够让您从DIDI开始进一步了解您的冒险活动的基本起点以及在哪里进一步发展。