0

私は現在、UnityとCaliburnMicroを使用してMVVMを実装する方法を学ぼうとしています。他の場所で助けを探した後、コンストラクタインジェクションを適切に設定する方法がまだわかりません。MVVMやその他の専門知識が不足しているために、これが機能していないかどうかはわかりません。

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

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

これは、Bootstrapper(Unity)クラスで使用しているコードです。

    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はStringsViewModelの2つのインスタンスを受け取ります。ただし、ステートメントにキーを入れる場合は、次のようになります。

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

次に、CampaignsViewModelの2つのインスタンスを渡します。CampaignViewModelとStringsViewModelの1つのインスタンスで渡すようにInjectionConstructorに指定する方法がわかりません。GetInstanceメソッドと関係があるのではないかと思いますが、よくわかりません。

どんな助けでも大歓迎です!

ありがとう。

4

2 に答える 2

1

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

DIフレームワークはどのようにしてどれがどれであるかを知るのでしょうか?回答:できません。

したがって、これの代わりに2つのインターフェイスを使用します。

 public MainWindowViewModel(ICampaignScreen campaignViewModel, IStringsScreen stringsViewModel)

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

 public interface ICampaignScreen : IScreen

また、IScreenに何かを追加する必要もありません。これらは、フレームワークがそれらを区別するための手段を提供するだけです。

于 2011-07-04T10:23:49.503 に答える
1

かわった:

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

に:

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

そして、これはうまくいきました。それが規則や原則に違反しているかどうかはわかりませんが、今のところは機能します。

于 2011-07-04T10:42:10.170 に答える