我正在使用MVVM设计模式创建WPF应用程序。我最近才开始学习这两种方法,但对基础知识的运作方式有了扎实的把握。
应用程序将包含与UI无关的类,例如网络线程和消息处理程序,以及用于保存和加载设置的类。
该计划的这些元素与UI没有明确的联系。应该如何创建和初始化它们?这些是应用范围广泛的"服务不适合特定的ViewModel,也不像模特那样。
有没有正确的方法呢?什么应该"拥有"并创建这些对象? (ViewModel,或者更确切地说,它们是静态的并自己创建?)
这是MVVM模型的图表,只需进行一些调整即可显示我要找的内容:(突出显示的文字和紫色框)
当"用户加入"在服务器接收到消息后,服务将向已订阅它的模型发送事件,并通知新用户。 ViewModel将看到此更改,并将用户的名称添加到UI。
答案 0 :(得分:2)
您可以拥有链接到UI特定功能的服务。 (例如,只有主窗口使用它们)并且还可以在许多窗口之间共享服务。
对于第一个场景,我通常在ViewModels中实例化服务 对于应用程序范围的服务,我宁愿在App.xaml.cs中创建实例并将引用传递给我的viewmodel。
以下是我的一个项目的示例。
private void Application_Startup(object sender, StartupEventArgs e)
{
ConnectionManager connMan = new ConnectionManager();
MainViewModel mvm = new MainViewModel(connMan);
new MainWindow(mvm).ShowDialog();
// TODO: save settings, etc. here
this.Shutdown();
}
如果您的服务不依赖于任何状态信息,您也可以使用静态类。这就是我通常用于设置管理的内容,例如。
编辑:对于您发布的示例,您必须问自己这个问题:
谁负责创建和维护网络管理器对象?
如果是ViewModel,它可以将对象托管在自身内部。如果它是由外部对象创建的,则将其传递给ViewModel。这两种方法都有利有弊,而且我现在没有足够的信息建议您使用其中一种方法。
答案 1 :(得分:1)
您可以使用DI容器并使用它注册您的服务。如果您使用依赖注入或使用DI容器作为服务定位器,那么这是个人偏好的问题。
服务定位器背后的基本思想是拥有一个知道如何获取应用程序可能需要的所有服务的对象。简单来说ServiceLocator是一个单例注册表。
依赖注入的基本思想是拥有一个单独的对象,即汇编程序,它使用适当的实现填充lister类中的字段。
良好的实施是Microsoft Unity Container。您可以将其用作DI容器或服务定位器。
答案 2 :(得分:0)
在这种情况下,请尝试在ObservablleCollection<T>
中保留一个列表(例如ViewModel
),并在模型中保留特定于模型的数据类型,如Person
,User
。
然后创建单独的命名空间,例如Workers
,Helpers
或Managers
,它们是静态类,仅负责其特定区域。例如:Workers / Sql / SqlWorker
,Workers / Network / NetworkWorker
。
稍后在ViewModel
中,在相应的命令中调用这些方法。
我认为这将是一个简单而先进的解决方案,因为工作人员不会互相干扰(如果只是通过抽象接口),除了他们不会连接到UI。