我有MVVM项目,我想在几个viewmodel之间从模型共享一个对象(singleton),这样做的好习惯是什么? 谢谢你的帮助
答案 0 :(得分:3)
如果对象是必需的并且没有提供价值而没有它通过Constructor Injection强制对象内的界面;不要通过注射推动混凝土类型总是使用接口。
由于您没有使用Unity之类的IoC容器,因此您需要在应用程序启动时创建单例实例,然后确保通过给定的ViewModel传入给定的实例构造函数根据需要。
更好的方法是将单例实例推送到可以提供所需行为的服务,然后忽略将单例推入模型。这将是一个更MVVM纯粹的方法,并将分离您的Models / ViewModels中的问题。
编辑:
如果您正在使用Unity,则在注册时定义Lifetime Manager。
// Register a type to have a singleton lifetime without mapping the type
// Uses the container only to implement singleton behavior
myContainer.RegisterType<MySingletonObject>(new ContainerControlledLifetimeManager());
// Following code will return a singleton instance of MySingletonObject
// Container will take over lifetime management of the object
myContainer.Resolve<MySingletonObject>();
执行此操作后,任何通过MySingletonObject
解析IUnityContainer
的尝试都将解析为同一实例,提供您在整个应用程序中所需的单例行为。 ViewModels本身不需要返回相同的实例。它所需的数据应该通过之前引用的服务抽象出来,这可能表现得像一个单例,并在需要时提供有状态实现,但ViewModel不需要是单例。如果您发现自己制作模型或ViewModel是单身人士;退后一步,分析你的设计。
答案 1 :(得分:2)
如果您可以控制所有视图模型,那么一种简单的方法(我个人使用过)就是在所有视图模型的基类上放置一个静态变量,并使所有继承者都可以访问它(受保护的,甚至是公共的)它在视图模型之外很有用。)
无论如何,为视图模型建立一个公共基类是很好的做法,因为它允许您在一个地方实现属性通知(以及其他常见功能,如消息传递等),而不是在所有视图模型中复制它。
这样的东西就是我在项目中使用的东西:
public class MyViewModelBase : INotifyPropertyChanged
{
private static MySharedSingleton _sharedObj;
static MyViewModelBase()
{
_sharedObj = new MySharedSingleton(/* initialize it here if needed */);
}
// or public
protected MySharedSingleton SharedObject { get { return _sharedObj; } }
// INotifyPropertyChanged stuff
// ...
}
public class SomeViewModel : MyViewModelBase
{
void SomeMethod()
{
SharedObject.DoStuff();
}
}
如果共享单例对象的构造很重,您当然可以使用它的任何standard techniques for lazy instantiation。
答案 2 :(得分:1)
我建议您将依赖项注入每个视图模型(例如构造函数或属性注入),并始终对视图模型中的抽象进行处理,以便可以根据需要轻松地模拟或替换依赖项。然后,您只需确保每个视图模型使用相同的类型实例 - 如果您使用的是IoC容器,则可以轻松注册类型的共享实例。
答案 3 :(得分:0)
我使用单独的类作为我的全局单例和模型。这使我对如何将此模型注入视图模型和其他模型感到痛苦。 E.g。
单身人士:
public class ApplicationModel
{
public string LoggedOnUser { get; set; }
// Etc.
private ApplicationModel() {
// Set things up.
}
private static ApplicationModel _active;
public static ApplicationModel Current {
get {
if (_active == null) {
_active = new ApplicationModel();
}
return _active;
}
}
}
视图模型不需要引用单例:
public class SomeViewModel
{
private string _user;
public SomeViewModel() {
_user = ApplicationModel.Current.LoggedOnUser;
}
}