app.xaml中定义的Silverlight ViewModelLocator需要对DI容器的引用

app.xaml中定义的Silverlight ViewModelLocator需要对DI容器的引用,silverlight,dependency-injection,blendability,Silverlight,Dependency Injection,Blendability,我在app.xaml中定义了一个ViewModelLocator类,视图使用该类将数据绑定到正确的ViewModel DataContext="{Binding HomeViewModel, Source={StaticResource Locator}}" 我使用的是Prism和Unity,我的ViewModelLocator类需要对应用程序级Unity容器的引用 我想将IUnityContainer注入ViewModelLocator的ctor中,但ViewModelLocator使用无参

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

DataContext="{Binding HomeViewModel, Source={StaticResource Locator}}"
我使用的是Prism和Unity,我的ViewModelLocator类需要对应用程序级Unity容器的引用

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

是否有更好的方法来访问应用程序级容器-对于应用程序中的所有其他类,我只是使用ctor注入来获取全局容器

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

protected override IUnityContainer CreateContainer()
{
    BootStrapper.DIContainer = base.CreateContainer();
    return BootStrapper.DIContainer;
}
然后在ViewModelLocator类中,我只引用BootStrapper.DIContainer属性来注册我的viewmodels

BootStrapper.DIContainer.RegisterType<IShellViewModel, DesignShellViewModel>();
BootStrapper.DIContainer.RegisterType();
这很好,但它是应用程序中唯一需要在引导程序上引用此静态属性的地方,如果可能的话,它希望将其删除

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

  • 向Unity注册VML
  • Boostrapper.cs:(UnityBootstrapper类)

    }

  • 删除VML并将其重新添加到应用程序资源。将字符串文字“Locator”替换为App.xaml ResourceDictionary部分中称为VML的内容
  • App.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>());
    }
    
    private void应用程序\u启动(对象发送方,StartupEventArgs e)
    {
    Bootstrapper Bootstrapper=new Bootstrapper();
    bootstrapper.Run();
    资源。删除(“定位器”);
    Add(“Locator”,bootstrapper.Container.Resolve());
    }
    

    您现在已启动、锁定并准备就绪。

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

  • 向Unity注册VML
  • Boostrapper.cs:(UnityBootstrapper类)

    }

  • 删除VML并将其重新添加到应用程序资源。将字符串文字“Locator”替换为App.xaml ResourceDictionary部分中称为VML的内容
  • App.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>());
    }
    
    private void应用程序\u启动(对象发送方,StartupEventArgs e)
    {
    Bootstrapper Bootstrapper=new Bootstrapper();
    bootstrapper.Run();
    资源。删除(“定位器”);
    Add(“Locator”,bootstrapper.Container.Resolve());
    }
    

    您的手机现在已翘起、锁定并准备好摇动。

    我想我应该跟进一下,因为它还没有被标记为已应答

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

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

    var vml = Application.Current.Resources["ViewModelLocator"] as ViewModelLocator;
    
    Container.BuildUp(typeof(ViewModelLocator), vml);
    
    第一行从App.xaml标记检索应用程序自动创建的实例。第二行使用Unity解析任何标记为DependencyAttribute的属性


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

    我想我应该跟进一下,因为它还没有被标记为已回答

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

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

    var vml = Application.Current.Resources["ViewModelLocator"] as ViewModelLocator;
    
    Container.BuildUp(typeof(ViewModelLocator), vml);
    
    第一行从App.xaml标记检索应用程序自动创建的实例。第二行使用Unity解析任何标记为DependencyAttribute的属性

    对我来说,这是一个更干净的解决方案。当然,它是不能混合的