複数の画面があり、WCF Web サービスと通信するアプリケーションがあります。お気に入りの IoC コンテナーには SimpleInjector を使用し、WPF を使用した MMVM には Caliburn Micro を使用しています。
ITransportClient
Web サービスへの接続を制御し、メッセージを送受信する別のクラス実装があります。
アプリケーションには次の状態があります。
- アプリケーションの起動と初期化。
- ログインフォームを表示します。
- ログインフォームは でチャットサーバーへの接続を行います
ITransportClient.Login(username, password)
。 - ログインに成功すると、新しい MainWindow ビューが表示されます。ログインに失敗した場合は、ユーザーに再度資格情報を求めるプロンプトを表示します。
- ログインすると、MainWindow は WCF サービスとの間で送受信されるメッセージを制御します。
- サーバーとの接続が失われた場合 ( で通知
ITransportClientCallback.OnTransportDisconnected
)、またはユーザーがログアウトをクリックした場合、ログイン フォームが再度表示されます。
私が利用できるテクノロジと、これが私の最初の MVVM プロジェクトであるため、次のアーキテクチャと設計に関する質問があります。
- 別のログイン画面を表示し、接続時にメイン画面を表示し、接続が失われたときにログイン画面に戻るには、どのデザイン パターンを使用すればよいですか?
- チャット アプリケーションの接続状態を制御するのは誰で、このコードはどこに配置しますか? この状態はブートストラップ クラスに含まれますか?
- ITransportClient を永続化インスタンス スコープとして登録し、それを必要とする ViewModel (つまり、ログイン フォームとメイン ウィンドウ フォームの両方) に挿入することで、必要に応じて複数のフォーム コントロールを使用できますか?
インターフェイスは次のITransportClient
とおりです。
public interface ITransportClientCallback
{
string OnReceivedMessage();
void OnTransportDisconnected();
}
// transport interface that client calls
public interface ITransportClient
{
bool SendLogin(string username, string password);
void SendLogout();
void SendMessage();
void RegisterCallback(ITransportClientCallback applicationHostCallback);
}
SimpleInjector を使用した Caliburn.Micro ブートストラップ コードと共に:
public class SimpleInjectorBootstrapper : Caliburn.Micro.Bootstrapper
{
private Container container;
protected override void Configure()
{
this.container = new Container();
this.container.Register<IWindowManager, WindowManager>();
this.container.Register<IEventAggregator, EventAggregator>();
this.container.Register<IAppViewModel, AppViewModel>();
this.container.RegisterSingle<ITransportClient, Transport.WCF.TransportClient>();
}
protected override object GetInstance(Type serviceType, string key)
{
return this.container.GetInstance(serviceType);
}
protected override IEnumerable<object> GetAllInstances(Type serviceType)
{
return this.container.GetAllInstances(serviceType);
}
protected override void OnStartup(object sender, System.Windows.StartupEventArgs e)
{
base.OnStartup(sender, e);
var appViewModel = this.container.GetInstance<IAppViewModel>();
var windowManager = this.container.GetInstance<IWindowManager>();
windowManager.ShowWindow(appViewModel);
}
}