1

我在 app.xaml 中定义了一个 ViewModelLocator 类,我的视图使用它来将数据绑定到正确的 ViewModel。

DataContext="{Binding HomeViewModel, Source={StaticResource Locator}}"

我正在使用 Prism 和 Unity,而我的 ViewModelLocator 类需要对应用程序级统一容器的引用。

我想将 IUnityContainer 注入 ViewModelLocator 的 ctor,但 ViewModelLocator 使用无参数 ctor 从 app.xaml 实例化。

是否有一种首选的方式来访问应用程序级容器 - 对于应用程序中的所有其他类,我只使用 ctor 注入来获取全局容器。

我现在为 ViewModelLocator 做的是在我的 BootStrapper 类中定义一个静态变量来存储容器。我通过覆盖 UnityBootStrapper 上的 CreateContainer 方法来创建容器。

protected override IUnityContainer CreateContainer()
{
    BootStrapper.DIContainer = base.CreateContainer();
    return BootStrapper.DIContainer;
}

然后在ViewModelLocator类中,我只引用 BootStrapper.DIContainer 属性来注册我的视图模型

BootStrapper.DIContainer.RegisterType<IShellViewModel, DesignShellViewModel>();

这工作正常,但它是应用程序中唯一需要在引导程序上引用此静态属性的地方 - 并且如果可能的话希望摆脱它。

谢谢迈克尔

4

2 回答 2

1

在将我的 Silverlight RIA Business 应用程序转换为使用 Prism、Unity 和 MVVM light 工具包时,我遇到了同样的问题。我想出了这个解决方法,就是让 App.xaml 创建我的 ViewModelLocator 类的实例,在应用程序启动事件期间,我从应用程序资源中删除它创建的实例,并使用 Unity 容器的Resolve方法重新添加一个实例。

  1. 向 Unity 注册 VML。

Boostrapper.cs:(UnityBootstrapper 类)

protected override void ConfigureContainer()
{
    Container.RegisterType<ViewModelLocator>(new ContainerControlledLifetimeManager());
    base.ConfigureContainer();
}
  1. 在 IUnityContainer 的 VML 中使用构造函数或属性注入。这里我使用属性注入。另请注意,默认的无参数构造函数是必需的,因为 App.xaml 将实例化它自己的实例,我们将最终丢弃。

ViewModelLocator.cs:(用于可混合性)

public class ViewModelLocator
{
    [Dependency]
    public IUnityContainer Container { get; set; }

    public ViewModelLocator() { }

....

}

  1. 删除 VML 并将其重新添加到应用程序资源。将字符串文字“Locator”替换为您在 App.xaml ResourceDictionary 部分中调用 VML 的任何内容。

应用程序.xaml.cs:

private void Application_Startup(object sender, StartupEventArgs e)
{
    Bootstrapper bootstrapper = new Bootstrapper();
    bootstrapper.Run();

    Resources.Remove("Locator");
    Resources.Add("Locator", bootstrapper.Container.Resolve<ViewModelLocator>());
}

你现在翘起,锁定,并准备好摇滚..

于 2011-01-23T09:36:10.707 回答
0

我想我会跟进这个,因为它没有被标记为已回答。

我对 Degree451 采用了类似的方法,只是我没有删除并重新添加定位器,因为它闻起来有点味道。相反,我使用 Silverlight 和 Unity 的内置功能来处理该问题。

在 ViewModelLocator 类中使用 Container 属性标记 DependencyAttribute 意味着该类可以在实例化后解析其依赖项。所以在我的引导程序中,我覆盖了 ConfigureContainer 并添加了以下代码:

var vml = Application.Current.Resources["ViewModelLocator"] as ViewModelLocator;

Container.BuildUp(typeof(ViewModelLocator), vml);

第一行从 App.xaml 标记中检索应用程序自动创建的实例。第二行使用 Unity 解析任何标有 DependencyAttribute 的属性。

对我来说,这是一个更清洁的解决方案。当然,它不是可混合的。

于 2011-08-31T22:42:32.953 回答