1

ビューが正しいViewModelにデータバインドするために使用するapp.xamlで定義しているViewModelLocatorクラスがあります。

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

Prism と Unity を使用しており、ViewModelLocator クラスにはアプリケーション レベルの Unity コンテナーへの参照が必要です。

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ライトツールキットを使用するように変換しているときに、同じ問題が発生しました。App.xaml に ViewModelLocator クラスのインスタンスを作成させ、アプリケーションの起動イベント中に作成したインスタンスをアプリケーション リソースから削除し、Unity コンテナーのResolveメソッドを使用してインスタンスを再度追加するという回避策を思いつきました。

  1. VML を Unity に登録します。

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 の両方の組み込み機能を使用して問題を処理します。

DependencyAttribute でマークされた ViewModelLocator クラスの Container プロパティを持つことは、インスタンス化後にクラスの依存関係を解決できることを意味します。したがって、Bootstrapper では、ConfigureContainer をオーバーライドして、次のコードを追加します。

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

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

最初の行は、アプリケーションによって自動的に作成されたインスタンスを App.xaml マークアップから取得します。2 行目では、Unity を使用して、DependencyAttribute でマークされたプロパティを解決します。

私にとって、これははるかにクリーンなソリューションです。もちろん、ブレンド可能ではありません。

于 2011-08-31T22:42:32.953 に答える