簡體   English   中英

在app.xaml中定義的Silverlight ViewModelLocator需要對DI容器的引用

[英]Silverlight ViewModelLocator defined in app.xaml needs a reference to the DI container

我在app.xaml中定義了一個ViewModelLocator類,我的視圖使用該類將其數據綁定到正確的ViewModel。

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

我正在使用Prism和Unity,並且我的ViewModelLocator類需要對應用程序級別統一容器的引用。

我想將IUnityContainer注入到ViewModelLocator的ctor中,但是使用無參數ctor從app.xaml實例化了ViewModelLocator。

有沒有一種首選的方法可以訪問應用程序級別的容器-對於應用程序中的所有其他類,我只是使用ctor注入來獲取全局容器。

我現在為ViewModelLocator做的事情是在BootStrapper類中定義一個靜態變量來存儲容器。 我通過覆蓋UnityBootStrapper上的CreateContainer方法來創建容器。

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

然后在ViewModelLocator類中,我只引用BootStrapper.DIContainer屬性來注冊我的視圖模型

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

這可以正常工作,但是它是應用程序中唯一需要在引導程序上引用此靜態屬性的位置-並希望盡可能地擺脫它。

謝謝邁克爾

在轉換我的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. 在VML中為IUnityContainer使用構造函數或屬性注入。 在這里,我正在使用屬性注入。 還要注意,默認的無參數構造函數是必需的,因為App.xaml將實例化其自己的實例,而我們最終將拋出該實例。

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

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

    public ViewModelLocator() { }

....

}

  1. 刪除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>());
}

您現在已翹起,鎖定並准備搖擺。

我認為我應該對此進行跟進,因為尚未將其標記為已回答。

除了不刪除並重新添加定位器(因為它聞起來有點)外,我對度451采取了類似的方法。 相反,我使用Silverlight和Unity的內置功能來解決問題。

將ViewModelLocator類中的Container屬性標記為DependencyAttribute意味着在實例化后可以解析該類的依賴項。 因此,在我的Bootstrapper中,我重寫ConfigureContainer並添加以下代碼:

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

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

第一行從App.xaml標記檢索由應用程序自動創建的實例。 第二行使用Unity解析標記有DependencyAttribute的所有屬性。

對我來說,這是一個更清潔的解決方案。 當然,它不是可混合的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM