0

私はかなりシンプルで標準的な MVVM WPF アプリを持っています。私は TinyIoC をコンテナーとして使用して、ViewModel の基になるデータとキャッシュ プロバイダーを提供しています。このコードを MonoTouch および Monodroid プロジェクトとも共有したいので、TinyIoC を使用しています。

ViewModels が TinyIoC からのデータ プロバイダーの解決に依存していないすべてのユーザー コントロールは、MainWindow の XAML に追加されたときに正常に動作します。

ViewModel が TinyIoC を使用してデータを取得するデータ プロバイダーを解決するユーザー コントロールは、MainWindow に追加されたときにデザイナー ビューでインスタンス化できません。

重要な注意: アプリを実行するとすべて正常に動作しますが、デザイナーが壊れているだけです。これは大きな障害です。

基本的なコードは次のとおりです。

    // From App.xaml.cs
    private void HandleAppStartupEvent(object sender, StartupEventArgs e) {
        IDataStoreProvider store = new XmlDataStoreProvider();
        ICacheProvider cache = new DictionaryCacheProvider();

        TinyIoCContainer.Current.Register(store);
        TinyIoCContainer.Current.Register(cache);
    }

View / ViewModel / XAML バインディングの標準実装 - ここでは問題ありません。

データ レイヤーの深さでは、IoC コンテナーを使用して、使用するプロバイダー (上記のコードで設定されたもの) を解決します。

public static class Gateway
{
    private static IDataStoreProvider store;
    private static ICacheProvider cache;

    static Gateway() {
        store = TinyIoCContainer.Current.Resolve<IDataStoreProvider>();
        cache = TinyIoCContainer.Current.Resolve<ICacheProvider>();
    }

    // use the store and cache here...

}

これは、デザイナーから得た正確なエラーです。

型を解決できません: C:_dev\Sample\SampleSolution\Sample.Core\Utility\TinyIoC.cs:line 3281 の TinyIoC.TinyIoCContainer.ResolveInternal(TypeRegistration registration, NamedParameterOverloads parameters, ResolveOptions options) の Sample.Core.Data.IDataStoreProvider TinyIoC.TinyIoCContainer.Resolve(Type resolveType) C:_dev\Sample\SampleSolution\Sample.Core\Utility\TinyIoC.cs:line 1314 at TinyIoC.TinyIoCContainer.ResolveResolveType in C:_dev\Sample\SampleSolution\Sample.Core\Utility \TinyIoC.cs:C:_dev\Sample\SampleSolution\Sample.Core\Data\Gateway.cs:line 14 の Sample.Core.Data.Gateway..cctor() の行 1433

このエラーが発生する理由を理解していると思います。デザイナーが MainWindow 内のユーザー コントロールを読み込んで実行する前に、IoC を読み込むためにアプリの起動イベントが発生しません。

繰り返しますが、アプリは正常に動作します-IoCとすべて。デザイナーの読み込みエラーを次のいずれかで停止したいと思います (優先順):

  • デザイナーで適切に動作するようにコードを修正する方法を理解する
  • デザイナーのモック データを使用して既存の制御データをスタブ化する
  • このデザイナー機能を無効にする
4

2 に答える 2

0

2 番目の箇条書きの解決策 (設計者用のモック データを使用して既存の制御データをスタブ化する)

ViewModel コンストラクターに次のコードを追加しました。

    public AdminViewModel(UserControl view) {
        this.view = view;

        var designMode = DesignerProperties.GetIsInDesignMode(view);

        if (designMode) {
            Items = new ObservableCollection<ItemModel>
                      {new ItemModel {Name = "Item1"}, 
                       new ItemModel {Name = "Item2"}};
        }
        else {
            Items= new ObservableCollection<ItemModel>(Gateway.GetItems());
        }   
    }

機能しますが、いくつかの懸念があります。

  • アプリ以外のロジックでコードを汚染する
  • ビューの参照をビューモデルに渡すように強制します

これをより「ブレンド可能」で、よりクリーンな方法でデザイナーに優しいものにしたいと思います - 他に何か考えはありますか?

于 2012-07-13T22:03:04.637 に答える
0

Windows/コンテナー ロード イベントのイベント ハンドラーにデータをロードしようとしていますか? そうすることで、過去にこの種の問題が発生しました。

于 2012-07-13T18:53:54.290 に答える