我有一个具有多个屏幕并与 WCF Web 服务对话的应用程序。我将 SimpleInjector 用于我最喜欢的 IoC 容器,将 Caliburn Micro 用于带有 WPF 的 MMVM。
我有一个单独的类实现,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);
}
}