でモーダルダイアログを実装する場合に依存性の注入とのServiceLocatorを交換します。私は私の最初のWPFアプリケーションを書いていますし、私は私が遭遇した問題に助けをお願いしたいと思いMVVM WPFアプリケーション
私はMVVMパターンを追跡しようとしていると私は、モーダルダイアログを実装する必要がポイントに来ました。私はいくつかの時間のためのトピックを読む/グーグルと私は解決策に落ち着くことができました。しかし、リファクタリングとき、私はサービスロケータの代替としてDI(コンストラクタ・インジェクション)を使用してに関するジレンマに遭遇しました。
私はこれらを参照するつもりです:http://pastebin.com/S6xNjtWW。
私は本当にRoboblobのアプローチのように:
まず:彼はモーダルダイアログ(インターフェース)の抽象化を作成します。私はインターフェイスIModalDialogを命名し、これは、それがどのように見えるかです:
public interface IModalDialog
{
bool? DialogResult { get; set; }
object DataContext { get; set; }
void Show();
bool? ShowDialog();
void Close();
event EventHandler Closed;
}
第二:モーダルダイアログサービスの抽象化:
public interface IModalDialogService
{
void ShowDialog<TDialogViewModel>(IModalDialog view, TDialogViewModel viewModel, Action<TDialogViewModel> onDialogClose) where TDialogViewModel : class;
void ShowDialog<TDialogViewModel>(IModalDialog view, TDialogViewModel viewModel) where TDialogViewModel : class;
}
サード: IModalDialogServiceの具体的な実装:
public class ModalDialogService : IModalDialogService
{
public void ShowDialog<TDialogViewModel>(IModalDialog view, TDialogViewModel viewModel, Action<TDialogViewModel> onDialogClose) where TDialogViewModel : class
{
// set datacontext
if (viewModel != null)
{
view.DataContext = viewModel;
}
((System.Windows.Window)view).Owner = System.Windows.Application.Current.MainWindow;
// register
if (onDialogClose != null)
{
view.Closed += (sender, e) => onDialogClose(viewModel);
}
view.ShowDialog();
}
public void ShowDialog<TDialogViewModel>(IModalDialog view, TDialogViewModel viewModel) where TDialogViewModel : class
{
this.ShowDialog(view, viewModel, null);
}
第4位: IModalDialogの複数の実装があります。それぞれIModalDialogを実装してウィンドウの派生クラスです。
私は(問題を記述)質問をする前に、私は事前にこれを説明する必要があります。
のは、私は、例えば、IMessageBoxServiceのためのようないくつかのより多くのサービスを、持っているとしましょう。 は、それから私はMainWindowViewModelのコンストラクタでこれらの依存関係を宣言する必要があります:私は彼ら(手でまたはユニティのようなIOCコンテナなどを使用してのいずれか)を注入することができます
public MainWindowViewModel(IModalDialogService a,
IMessageBoxService b,
...)
ように。
パズルの一つ欠けている部分があるモーダルダイアログサービスを利用できるようにするために - いくつかのキーに基づいてIModalDialogの具体的な実装を解決する能力が。
彼の記事でRoboblobはのServiceLocatorパターンを使用して、パズルのこの最後のピースを解決:
public class Bootstrapper
{
public static void InitializeIoc()
{
SimpleServiceLocator.SetServiceLocatorProvider(new UnityServiceLocator());
SimpleServiceLocator.Instance.Register<IModalDialogService, ModalDialogService>();
SimpleServiceLocator.Instance.Register<IMessageBoxService, MessageBoxService>();
...
SimpleServiceLocator.Instance.Register<IModalWindow, EditUserModalDialogView>(Constants.EditUserModalDialog);
}
}
ので、彼のMainWindowViewModel内部の彼は単に静的なクラスが取得呼び出すとIModalDialogウィンドウの具体的な実装を解決しますキーに基づきます。
でもジョシュ・スミスは彼の記事では、同様のアプローチを使用していますが、コメントで、彼は(DI - コンストラクタ・インジェクション)がいるという有効なオプションです。
参照StackOverflowの答えも変更して使用することができ似たWindowViewLoaderServiceを説明しています。
そこで質問です - 依存性注入と(IModalDialogの具体的な実装を解決)のServiceLocatorを交換するための最良の方法だろうか?
思考の私の列車がした
一つの可能性だけで作成します(例えばIModalDialogResolverと呼ばれる)新しいサービスを作成するために、(原因プロジェクトは、私だけが開発した/非常に大きなされていないために)で、 IModalDialogの具象実装の新しいインスタンスを返します。すべてのサービスを手作業で注入する。
私はIOCコンテナ(ユニティ)について考えました。私はそれについての経験はない。 IModalDialogの異なる実装をUnity container =>に登録することができるので、IModalDialogResolverを記述する必要はないと思ったが、MainWindowViewModelの中でどのようにコンテナを使うのだろうか? ServiceLocationのステップに戻るので、コンストラクタへの参照を渡すことはできません。
それでは、ブートストラッパー内の単一のコンテナを使用して、すべてのサービスを解決し、IModalDialogResolverの内部で別のサービスを使用することができると考えました。しかし、これがUnityの推奨される使用法に関する良いアイデアかどうかは分かりません。私は本当にこれを判断するにはほとんど知りません。しかし、コンテナがコンストラクタに参照を渡すのと同等のシングルトンの場合、コンテナに隠された依存関係を作成するため、これは良い考えではないことがわかります。
私が持っているメンタルブロックをもっとよく説明するには:IOCコンテナ(例えば、Unity)を使用して、インターフェイスを構築して注入したいと考えています。しかし、私は単なるコンストラクタの中にパラメータとしてIModalDialogを置くことはできません。だからおそらく私は本当にこれをサービスの中に包み込んで自分自身を実装する必要があります - しかし、(Unityがこれを箱から出すことができれば)私はそれを使うことができなければUnityを最初にそこに持つことは理にかなっていません。
私は、この1つのサービスを基本クラスに入れることをお勧めしますが、議論のために、これを考慮しません。私は本当にこれを依存性注入を使って解決する正しい方法について学びたいと思っています。
依存性注入とサービスの場所は互いに排他的ではありません。依存関係注入を使用してサービスロケータを注入できます。また、MVVMでメッセージボックス/ダイアログを使用するための2つの異なるアプローチ(対話サービスと対話要求)については、これを参照してください:http://stackoverflow.com/questions/16877671/showing-a-message-box-from-the-viewmodel-is -a-violation-of-mvvm-how-to-avoid – lightbricko
@lightbrickoまず、ご返信ありがとうございます。 :)私は "インタラクションサービス"を正しく理解しているので、IModalDialogResolver用のインターフェイスを作成し、インプリメンテーションを注入するのが最適でしょうか?質問:私たちがUnityをboostrapper依存性注入に使用したとしましょう。あなたがIModalDialogResolverを実装するためにUnityを使うことができると思うのですか? – kajovajo
@lightbricko依存性注入とサービスの場所は、同じ問題に対する反対の解決策です。技術的には、それらは相互に排他的ではありませんが、それらを混合することによって得られるものはありません。 http://www.infoq.com/articles/Succeeding-Dependency-Injection –