2016-05-12 12 views
-1

する前に作成されていることを、私はこのようになりますViewModelLocatorを使用してC#/ WPF/MVVM/UWPアプリを開発していていることを確認しますこのように見えるナビゲーションの目的のために:両方のクラスがViewModelLocatorで組み合わせた、前は1つの静的クラスが他の

public class ViewLocator 
{ 
    public static readonly string MainPageKey = typeof(MainPage).Name; 
    public static readonly string WorkPageKey = typeof(WorkPage).Name; 

    static ViewLocator() 
    { 
     ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default); 

     var navigationService = new NavigationService(); 

     navigationService.Configure(MainPageKey, typeof(MainPage)); 
     navigationService.Configure(WorkPageKey, typeof(WorkPage)); 

     SimpleIoc.Default.Register<INavigationService>(() => navigationService); 

     SimpleIoc.Default.Register<IDialogService, DialogService>(); 
    } 
} 

、しかし、私は「のviewmodelsサイド・オブ・もの」の一環としてViewModelLocatorが意見を知らないであることを考え出しとそれは型です。そのため、私はそのコードを2つのクラスにリファクタリングしました。

マイMainPageViewが、その後完全については

public class MainPageViewModel : ViewModelBase 
{ 
    private INavigationService _navigationService; 

    public RelayCommand CreateNewImageCommand { get; private set; } 

    public MainPageViewModel(INavigationService navigationService) 
    { 
     _navigationService = navigationService; 

     CreateNewImageCommand = new RelayCommand(CreateNewImage,() => true); 
    } 

    public void CreateNewImage() 
    { 
     _navigationService.NavigateTo(Views.ViewLocator.WorkPageKey); 
    } 
} 

MainPageView.csにナビゲーションコマンドをトリガーボタンがあり、ここで

<Application 
...> 

<Application.Resources> 
    <v:ViewLocator x:Key="ViewLocator" /> 
    <vm:ViewModelLocator x:Key="ViewModelLocator" /> 
</Application.Resources> 

今私のApp.xamlあるものこれは、私がViewModelLocatorにDEBUG LINEを持たない場合、MainPageがViewModelLocatorからViewModelを要求した時点で、ViewLocatorのコンストラクタにまだ呼び出されておらず、return ServiceLocator.Current.GetInstance<MainPageViewModel>();が例外をスローします。 DEBUG LINEを含めると、ViewLocatorコンストラクターが最初に実行され、すべて正常に動作します。

この奇妙なデバッグラインなしでこの動作を実現するにはどうすればよいですか?

+0

私はこれをここに残すつもりです[ServiceLocator anti-pattern](http://stackoverflow.com/questions/22795459/is-servicelocator-anti-pattern) – Liam

+0

TL; DR実際に依存関係を使用する必要がありますインジェクションはサービスロケータのパターンではありません。典型的には、ゼロから始めれば、理解するのがはるかに簡単で簡単です。 – Liam

+0

@Liam私はIoC ContainersやServiceLocatorのファンではありません。 VMとVを適切に分離する方法を研究しており、これまで私が満足している唯一の方法です。しかし私はDIを使用することに非常に寛容です - もしあなたが私に適切にそれを採用するいくつかの参照コードを表示してください。 – Xaser

答えて

0

ほとんどの開発者が静的クラスとサービスロケータを使用しないという理由で、あなたは実行しています。

あなたのコメントに示唆されているように、依存性注入を試してみてください。これにより、この配線を管理するコンポーネントの制御を反転することができます。

独自のIoCを使用するのではなく、使用するフレームワークとしてMEFまたはUnityを調べます。両方とも長所と短所を持っていますが、どちらもうまくいきます。また、より簡単でクリーンなテストも可能です。

MEF

Unity

0

すべてのコメントや他の回答のにもかかわらず、私はすべての後に軌道に乗ったと思います。この問題を解決するか、むしろ回避するために、私はアプリケーションの起動時にSimpleIoCコンテナの追加ブートストラップを作成し、コードをViewLocatorのコンストラクタからそこに移動しました。

ServiceLocatorの呼び出しも削除されました。これは冗長であり、今すぐ直接SimpleIoC.Defaultに依存しています。

ナビゲータはまだSimpleIoCコンテナによってViewModelsに注入されます。ただし、ViewModelLocatorはXAMLコードと連携して必要な作業です。

私は、この問題に苦労している他の人の出発点として、この回答をお勧めします。

https://stackoverflow.com/a/25524753/2175012

すべての後、私はServiceLocatorsは何アンチパターンではないが、慎重に使用する必要がある側をとっています。

関連する問題