0

現在、UnityとCaliburn Microを使用してMVVMを実装する方法を学習しようとしています。他の場所で助けを探してみたら、Constructor Injectionを適切に設定する方法についてはまだ分かりません。 MVVMや他の何かの専門知識が不足しているためにこれが動作しないのかどうかはわかりません。複数のパラメータを持つUnity/Caliburn Micro、注入コンストラクタ

私の問題は、ユーザーがボタンをクリックしたときに移動できるメインウィンドウ(シェル)クラスに2つのIScreenオブジェクトを渡したいということです。ここに私のMainWindowViewModelクラスのコンストラクタのコードです:

private IScreen campaignViewModel, stringsViewModel; 
public MainWindowViewModel(IScreen campaignViewModel, IScreen stringsViewModel) 
{ 
    this.campaignViewModel = campaignViewModel; 
    this.stringsViewModel = stringsViewModel; 
    ActiveItem = this.campaignViewModel; 
} 

これは私が私のブートストラップに使用していたコードがあるが(ユニティ)クラス:

private static IUnityContainer BuildContainer() 
    { 
     IUnityContainer result = new UnityContainer(); 
     result 
      .RegisterInstance(result) 
      .RegisterInstance<IWindowManager>(new WindowManager()) 
      .RegisterInstance<IEventAggregator>(new EventAggregator()); 

     result 
      .RegisterType<IScreen, CampaignsViewModel>() 
      .RegisterType<IScreen, StringsViewModel>() 
      .RegisterType<MainWindowViewModel>(new InjectionConstructor(typeof(IScreen), typeof(IScreen))); 

     return result; 
    } 

    protected override object GetInstance(Type service, string key) 
    { 
     var result = unity.Resolve(service, key); 

     if (result == null) 
      throw new Exception(string.Format("Could not locate any instance of contract {0}", service)); 
     return result; 
    } 

これはMainWindowViewModelを実行する2つのインスタンスを受け取りますStringsViewModel。

result.RegisterType<IScreen, StringsViewModel>("StringsView"); 

次に、私はCampaignsViewModelの2つのインスタンスを渡します。 InjectionConstructorにCampaignViewModelとStringsViewModelの1つのインスタンスを渡す方法を指定する方法がわかりません。 GetInstanceメソッドと何か関係があるかもしれないと感じていますが、わかりません。

ご協力いただければ幸いです!

ありがとうございました。

答えて

1

コンストラクターでは、同じインターフェースを2回定義します。

どのようにDIフレームワークがどちらを知っていますか?答え:それはできません。代わりに、この使用のそう

2つのインターフェイス:

public MainWindowViewModel(ICampaignScreen campaignViewModel, IStringsScreen stringsViewModel) 

あなたはこれらの両方がIScreenから継承させることができます。

public interface ICampaignScreen : IScreen 

とどちらIScreenに何も追加必要 - 彼らは単にフレームワークがそれらを区別するための手段を提供する。

+0

まあ、私はちょうど注射を変更しました: 新しいInjectionConstructor(typeof(CampaignsViewModel)、typeof(StringsViewModel))とそれを行った。私はそれぞれのビューモデルのためのインターフェイスを作成するあなたの方法を試みたが、私はそれをコンパイルすることができませんでした。とにかくおかげで。 – stuartmclark

+0

あなたの答えを振り返ってみると、私はあなたが正しかったことを実感しました。私がしたことはうまくいきましたが、実際にはインターフェースを解決するよりも、ハックが増えました。各ViewモデルのIScreenから派生したインターフェイスを作成することは正しい動きでした。ありがとう。 – stuartmclark

1

は変更:

result 
      .RegisterType<IScreen, CampaignsViewModel>() 
      .RegisterType<IScreen, StringsViewModel>() 
      .RegisterType<MainWindowViewModel>(new InjectionConstructor(typeof(CampaignsViewModel), typeof(StringsViewModel))); 

そして、これが働いた:

result 
      .RegisterType<IScreen, CampaignsViewModel>() 
      .RegisterType<IScreen, StringsViewModel>() 
      .RegisterType<MainWindowViewModel>(new InjectionConstructor(typeof(IScreen), typeof(IScreen))); 

へ。ルールや原則に違反しているのかどうかはわかりませんが、今のところうまくいきます。

関連する問題