2016-04-27 6 views
1

これは少し複雑ですので、すべてをお読みください。私はWPFのMVVMパターンを実装するいくつかのコードに取り組んでいます。私はdatacontext上の特定のプロパティを探すXAMLマークアップ拡張を持っています。 (これは長くて楽しい話ですが、範囲外です)私のビューモデルは、ビューのDataconextとして設定されます。ここで継承依存性注入の簡素化

が何が起こっているのか

public class ViewModelBase : IViewModelBase 
{ 
    protected CommandManagerHelper _commandManagerHelper; 

    //todo find a way of eliminating the need for this constructor 
    public OrionViewModelBase(CommandManagerHelper commandManagerHelper) 
    { 
     _commandManagerHelper = commandManagerHelper; 
    } 

    private IExampleService _exampleService; 

    public IExampleService ExampleService 
    { 
     get 
     { 
      if (_exampleService == null) 
      { 
       _exampleService = _commandManagerHelper.GetExampleService(); 
      } 

      return _exampleService; 
     } 
    } 
} 

私は_exampleServiceをロード効果的に怠け者だということです...私は私のBaseViewmodelを実装しているかの例です。私はLazyを使用することは可能だと確信していますが、実装するのはまだ遅れていません。

私のXaml Markupは、ExampleServiceを探して、ビューモデル内のコードでも使用できるようにします。これはアプリケーション全体で使用される予定です。

私のアプリケーションには、渡されるExampleServerのインスタンスが1つしかないことに注意してください。アプリケーションのどこからでもGetExampleServiceを呼び出すと、オブジェクトの同じインスタンスが返されます。 Singletonとしてコード化されていませんが、ExampleServiceオブジェクトのインスタンスは1つしかありません。ここで

は、このコードは動作し、素晴らしい作品

internal class ReportingViewmodel : ViewModelBase 
{ 
    private readonly IReportingRepository _reportingRepository; 

    public ReportingViewmodel(CommandManagerHelper commandManagerHelper, IReportingRepository reportingRepository) : base(commandManagerHelper) 
    { 
     _reportingRepository = reportingRepository; 
    } 
} 

...私は私のViewModelBaseから継承しています方法の例です。しかし、ViewModelBaseの新しい継承メンバーを実装するたびに、 ":base(commandManagerHelper)"と入力すると、間違いが起きやすくなります。私はこれらの実装の100を持っている可能性があり、それぞれが正しいことが必要です。

私が思っているのは、ソリッドの原理を尊重し、ViewModelBaseのインスタンスを実装するたびにベースのコンストラクタを呼び出す必要がない同じ動作を実装する方法はありますか?

つまり私はReportingViewModelこの

internal class ReportingViewmodel : ViewModelBase 
{ 
    private readonly IReportingRepository _reportingRepository; 

    public ReportingViewmodel(IReportingRepository reportingRepository) 
    { 
     _reportingRepository = reportingRepository; 
    } 
} 

のように見えるが、それでもExampleService、正しく装着したいのですが。

私は現在、このサービスロケータパターンの使用を検討しています。私はシングルトンを使用することも検討しています。私は他のより優れたソリューションにもオープンしています。

コードでダイブするのではなく質問するのは、シングルトンが一般に反パターンであることを知っているからです。コード内で何か他のものが間違っていることを意味しています。 私はIoCに関する記事を読んだだけです。サービスロケータのパターンについては、http://www.devtrends.co.uk/blog/how-not-to-do-dependency-injection-the-static-or-singleton-containerの記事をご覧ください。

答えて

2

基本コンストラクタを呼び出すことができません。 IExampleServiceは一度インスタンス化されて共有されるだけでは問題ありません。あなたのViewModelBaseはそのことを「知っている」ことはありません。それが知る必要があるのは、注入されたものがそのインターフェースを実装するということだけです。 ユニットテストクラスを作成すると、そのインタフェースの模擬バージョンを注入できるので、大きなメリットの1つです。クラスが基本クラス内に埋め込まれたものへの静的な参照に依存している場合、それをテストのためのモックに置き換えることはできません。

私はReSharperを使用します。 (私はそれを言うことが許されていますか?私は宣伝するつもりはありません)他の多くのものの中で、それはあなたのためのそれらの基本コンストラクタを生成します。ある時点ではVisual Studioに組み込まれているはずです。

+0

私はReSharperも使用しています。 :D私はこのソリューションの最良の実装を探しています。 –

+0

問題の別の部分があると思います。私は私のカスタムマークアップ拡張機能を使用してビューを持っているビューdatacontext本当にビューモデル(それは簡単な表示ダイアログです)を必要としないセットを持っているマークアップはIExampleService、ビューではなく、知っている必要があります。 ViewModel全体を作成するのはまだ正しいですか?それともマークアップで他の場所からエクステンションを引っ張ってもいいですか? (それが大丈夫なら、私はビューモデルがどのように構成されているかを変えることができます)それを行う方法を理解する必要があります。 –

+0

リフレクションでは、マークアップ拡張機能をviewmodelなしで動作させることについての質問は、別の話題です。 –