web-dev-qa-db-ja.com

.NET Core 3.0 for WPFでの依存性注入

私は、ASP.NET Coreと、すぐに使える依存関係注入のサポートに精通しています。コントローラは、コンストラクタにパラメータを追加することにより、依存関係を要求できます。 WPF UserControlsで依存関係をどのように実現できますか?コンストラクタにパラメータを追加しようとしましたが、うまくいきませんでした。私はIOCコンセプトを気に入っており、これをWPFに持ち込むことを望んでいます。

7
user842818

WPFでは、Model-View-ViewModel(略してMVVM)と呼ばれるパターンを使用します。依存関係がビューモデルに挿入され(ASP.NETで使用するのと同じIoCフレームワークを使用して、AutoFacなど)、ビュー(UserControls)がデータテンプレートとしてビューモデルに登録されます。

このようにして、ビューモデルに基づいてアプリケーションを構造化すると、ビューモデルがビューに依存しているかのように、ビューモデルに依存するビューが解決されます。ビューは、DataContextプロパティを介してビューモデルにアクセスできます。したがって、ビューモデルをファサードとして使用して、ビューに何でも注入できます。

その場合、コードビハインドを使用する必要があります。ただし、UserControlまたはxamlからインスタンス化された他のクラスに依存関係が本当に必要な場合は、よく考えてください。

0
Lukáš Koten

一般的に言えば、そうではありません。ビューモデルで依存関係注入を使用し、次にデータバインディングを使用してビューをビューにバインドします。

それができないと言っているのではありません。たとえば、MVVM Lightはインジェクタークラスを作成してから、そのインスタンスをApp.xamlで宣言します。これは、グローバル変数の宣言とほぼ同じです。

<Application.Resources>
    <ResourceDictionary>
        <vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True" xmlns:vm="clr-namespace:MyMvvmProject.ViewModel" />
    </ResourceDictionary>
</Application.Resources>

ビジュアルツリーの一部であるウィンドウとユーザーコントロールはアプリケーションリソースにバインドできるため、そのフレームワークでは、メインウィンドウは通常、次のようにビューモデルにバインドします。

<Window x:Class="MyMvvmProject.MainWindow"
    ...
    DataContext="{Binding Source={StaticResource Locator}, Path=Main}">

...ここで、Mainはロケータークラスのプロパティです。

public MainViewModel Main
{
    get
    {
        return ServiceLocator.Current.GetInstance<MainViewModel>();
    }
}

これは、すべての注射剤を単一のクラスに配置するため、あまり良いIoCではありません。実際には、さまざまなレベルで専門の工場などに分割します。

しかし真剣に、これは何もしないでください。ビューモデルレイヤーでDIを使用し、緩いデータバインディングを使用してビューに結合します。これにより、依存関係の注入のすべての機能を、部分的には不要なレイヤーから切り離すことで、また部分的には、Web、デスクトップ、モバイル、特にユニットテストなどの異なる環境で依存関係を再構成する柔軟性を可能にすることで、活用できます。ビューがまったく作成されない場所。

(免責事項:WPFで.NET Coreをまだ使用していないため、ここで説明した内容は.NET固有のものかもしれませんが、一般的な原則は残っています)。

0
Mark Feldman

いい質問です。xamlにパラメーター化されていないコンストラクターがないと、コントロールを作成できません。必要に応じて、コードからインスタンス化する必要がありますが、xamlはそのコンストラクターを呼び出しません。

0
OptimusPrime