依赖注入是否可以通过WPF应用程序? [英] Is Dependency Injection possible with a WPF appliction?

查看:200
本文介绍了依赖注入是否可以通过WPF应用程序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在我的WPF应用程序中开始使用依赖注入,主要是为了更好的单元可测试性。我的应用程序大多是沿着M-V-VM模式构建的。
我正在查看我的IoC容器的 autofac ,但是我不认为这个问题太重要了。



将服务注入起始窗口看起来很简单,因为我可以在App.xaml.cs中创建容器并解决它。



我是如何将DI ViewModels和服务转换成用户控件?用户控件通过XAML标记进行实例化,所以没有机会将 Resolve()他们。



最好的可以想到的是将容器放在Singlton中,并让用户控件从全局容器中解析其ViewModels。这个感觉就像一个中间解决方案,最好的是,因为它仍然要求我的组件对ServiceLocator有依赖。



WPF是否可以使用IoC? p>

[P]已经提出棱镜,但即使评估棱镜似乎是一个很大的投资,我希望能够减少一些



这里是一个我停止的代码片段

  //设置IoC容器(在app.xaml中.cs)
var builder = new ContainerBuilder();
builder.Register< NewsSource>()。As< INewsSource>();
builder.Register< AViewModel>()。FactoryScoped();
var container = builder.Build();

//用户控件ctor -
//这不起作用,我从哪里获取容器
VM = container.Resolve< AViewModel>();

//在app.xaml.cs
//这个编译,但我不能使用这个uc,
//作为我想通过xaml创建的一个主窗口
SomeUserControl uc = new SomeUserControl();
uc.VM = container.Resolve< AViewModel>();


解决方案

其实很容易做到。我们在Prism中提到了jedidja的例子。您可以使ViewModel注入视图或视图注入ViewModel。在Prism StockTraderRI中,您将看到我们将View注入到ViewModel中。 View(和View界面)本质上是一个Model属性。该属性在codebehind中实现,以将DataContext设置为该值,例如: this.DataContext = value; 。在ViewModel的构造函数中,View被注入。然后设置 View.Model = this; ,它将自己传递给DataContext。



你也可以轻松地做相反,并将ViewModel注入到视图中。我实际上更喜欢这个,因为这意味着ViewModel根本不再有任何对视图的引用。这意味着当单元测试ViewModel时,您甚至没有一个视图甚至Mock。此外,它使代码更清洁,因为在View的构造函数中,它只是将DataContext设置为注入的ViewModel。



我更多地谈论这个在分享的演示文稿模式的视频录制中,杰里米·米勒和我在Kaizenconf中给出的。其中第一部分可以在这里找到 http://www.vimeo.com/2189854



希望这有帮助,
格伦


I want to start using dependency injection in my WPF application, largely for better unit testability. My app is mostly constructed along the M-V-VM pattern. I'm looking at autofac for my IoC container, but I don't think that matters too much for this disucssion.

Injecting a service into the start window seems straightforward, as I can create the container and resolve from it in App.xaml.cs.

What I'm struglling with is how I can DI ViewModels and Services into User Controls? The user controls are instantiated via XAML markup, so there's no oportunity to Resolve() them.

The best I can think of is to place the container in a Singlton, and have the user controls resolve their ViewModels from the global container. This feels like a half-way solution, at best, as it still required my components to have a dependency on a ServiceLocator.

Is full IoC possible with WPF?

[edit] - Prism has been suggested, but even evaluating Prism seems like a big investment, I'm hoping for something smaller

[edit] here's a code fragment where I'm stopped

    //setup IoC container (in app.xaml.cs)
    var builder = new ContainerBuilder();
    builder.Register<NewsSource>().As<INewsSource>();
    builder.Register<AViewModel>().FactoryScoped();
    var container = builder.Build();

    // in user control ctor -
    // this doesn't work, where do I get the container from
    VM = container.Resolve<AViewModel>();

    // in app.xaml.cs
    // this compiles, but I can't use this uc, 
    //as the one I want in created via xaml in the primary window
    SomeUserControl uc = new SomeUserControl();
    uc.VM = container.Resolve<AViewModel>();

解决方案

It's actually very easy to do. We have examples of this in Prism as jedidja mentioned. You can either have the ViewModel get injected with the View or the View get injected with the ViewModel. In the Prism StockTraderRI you will see that we inject the View into the ViewModel. Essentially what happens is that the View (and View interface) has a Model property. That property is implemented in the codebehind to set the DataContext to the value, for example: this.DataContext = value;. In the constructor of the ViewModel, the View gets injected. It then sets View.Model = this; which will pass itself as the DataContext.

You can also easily do the reverse and have the ViewModel injected into the View. I actually prefer this because it means that the ViewModel no longer has any back reference to the view at all. This means when unit-testing the ViewModel you don't have a view to even Mock. Additionally it makes the code cleaner, in that in the constructor of the View, it simply sets the DataContext to the ViewModel that was injected.

I talk a bit more about this in the video recording of the Separated Presentation Patterns talk that Jeremy Miller and I gave at Kaizenconf. The first part of which can be found here http://www.vimeo.com/2189854.

Hope this helps, Glenn

这篇关于依赖注入是否可以通过WPF应用程序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆