WPFでのNinjectコンストラクタインジェクション

依存性注入のためにninjectを使用することは、結果がMVCで得られる注入のようなものになるようにすることが可能ですか?具体的には、MVCのninjectアダプターを使用すると、Webコントローラーをコンストラクター・パラメーターとして宣言することができます。このパラメーターは、自動的にninjectによって注入されます。

しかし、私はWPFのためのこのような拡張モジュールを見つけられませんでした。これにより、次のようなウィンドウができました:

public partial class MainWindow : Window
{
    private readonly IService injectedService;
    public MainWindow(IService injectedService) 
    {
        this.injectedService = injectedService;
    }
}

メインアプリケーションの起動時に IKernel を明示的に使用せずにmainwindowのインスタンスを取得したいとします。私は主ウィンドウとすべての後続のウィンドウのインスタンスを取得するために、xaml構成の通常の方法を使用する方が好きです。

これは可能ですか? xamlによって生成されたオブジェクトの作成をフックして、Ninjectを使用してコンストラクタの依存性注入を行う方法はありますか?

14
WPFでは通常、MVVMパターンを使用するため、ViewModelクラスにサービスを注入するため、このような拡張は存在しません。
追加された 著者 Daniel Hilgarth,
いいえ、ViewModelはXAMLでは作成されません。それらはViewModelLocatorで作成されます。ここを参照してください。ビューまたはViewModelは依存性注入コンテナについて何も知らない。
追加された 著者 Daniel Hilgarth,
ViewModelLocatorがコンポジションルートになるため、どちらでもありません。
追加された 著者 Daniel Hilgarth,
しかし、XAMLを介して作成されたモデル自体ではありませんか?確かに、私はWPFの専門家ではありませんが、モデルは従属注入と同じ種類のものを必要としませんか?私はコンテナを見せてプロジェクトの単体テストを妨げることに懸念しています。
追加された 著者 Dervall,
しかし、ViewModelLocatorはそれについて知っています。私はこれがうまくいると思うけど、それは私のservicelocator(アンチ)パターンと、自動的に処理された可能性がある注入カーネルの周りを包み込む余分な層のような感じです。
追加された 著者 Dervall,

1 答え

Based on the comments & your confusion, it looks like MVVM is a good match for you. The challenge is, LEARNING MVVM.

だから、良いリンクを開いて回転させてください。 MVVMは驚くほど簡単で、Ninjectですべてを包み込み、それに弓をかけるのはかなり簡単です。

あなたがNinject + MVVMのためにサードパーティ製のライブラリを使用しないと、最初の学習曲線は少し険しいです。ここで私が理解しなければならないことがいくつかあります:

        DataContext="{Binding Path=ResultViewModel,Source={StaticResource ServiceLocator}}"

この少し追加することで、ninjectを起動してXAMLからビューモデル情報を取得することができます。


    

この小さなトリックでは、app.xamlファイルのstaticresourceを関連するクラスに割り当てることができます

public class NinjectServiceLocator
{
    private readonly IKernel kernel;

    public NinjectServiceLocator()
    {
        kernel = new StandardKernel(new MyMvvmModule());
    }

    public ResultViewModel ResultViewModel
    {
        get { return kernel.Get(); }
    }
}

これは注目に値する。 Ninjectがそれらを生成するためには、すべてのviewmodelをServiceLocatorのプロパティとしてリストする必要があります。最後に、上の例のMyMvvmModuleは標準のNinjectクラスです。ここでは、Load()のオーバーライドをスティックし、すべてのインターフェイスをバインドします。

17
追加された
@Dervallありがとう。このようなポストは、私がJeff AtwoodがSOのために想像したものです。私も同様の問題があったので、何時間も調査した後に知った情報を共有して、今後誰かを救うことができればと思います。
追加された 著者 deltree,
ありがとう、非常に有用です
追加された 著者 Dervall,