这是我的定位器。出于演示目的,我剥离了除两个之外的所有ViewModel。由于我基本上需要注册所有: ViewModelBase
个对象,因此我考虑使用反射来执行此操作。类本身的属性不能被创建"像这样,但注册可以。但是,我在这里努力反思泛型方法。
using GalaSoft.MvvmLight.Ioc;
using Microsoft.Practices.ServiceLocation;
using System;
namespace DevExplorer
{
public class ViewModelLocator
{
public WindowMainViewModel WindowMain => SimpleIoc.Default.GetInstance<WindowMainViewModel>();
public WindowAboutViewModel WindowAbout => ServiceLocator.Current.GetInstance<WindowAboutViewModel>(GetKey());
public ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
//REFACTOR: Get by reflection
SimpleIoc.Default.Register<WindowMainViewModel>();
SimpleIoc.Default.Register<WindowAboutViewModel>();
}
private string GetKey()
{
return Guid.NewGuid().ToString();
}
}
}
答案 0 :(得分:0)
通常情况下,制定一个正确的问题需要我深入挖掘,所以一段时间后我想出了ViewModelLocator
构造函数的代码。我想分享一下,因为我觉得这至少是有点常见的MVVM Light问题,我还没有找到任何解决方案。
ViewModelBase
。Register
SimpleIoc
方法。现在,我没有比找到&#34;找到&#34;更好的主意。它使用.Where
。 请随时改进此声明! MakeGenericMethod
与ViewModelBase
衍生物的类型一起使用。Type[] viewModels = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(assembly => assembly.GetTypes())
.Where(type => typeof(ViewModelBase).IsAssignableFrom(type) && type != typeof(ViewModelBase))
.ToArray();
MethodInfo registerMethod = typeof(SimpleIoc)
.GetMethods()
.Where(method => method.Name == nameof(SimpleIoc.Default.Register) && method.GetParameters().Length == 0 && method.GetGenericArguments().Length == 1)
.First();
foreach (Type viewModel in viewModels)
{
registerMethod
.MakeGenericMethod(viewModel)
.Invoke(SimpleIoc.Default, new object[0]);
...使用ViewModelLocator类顶部的属性:我不认为它可以通过反射和误用XAML完成,因为这对我来说似乎不是好习惯。但是,为了让生活更轻松,我创造了一个简单的方法。
singleton
参数定义实例应该是单个实例还是每次获取唯一键。我在我的应用程序中将MainWindow定义为单例,而其他ViewModel在我的场景中不是单例。
public WindowMainViewModel WindowMain => GetInstance<WindowMainViewModel>(true);
public WindowAboutViewModel WindowAbout => GetInstance<WindowAboutViewModel>(false);
private static TService GetInstance<TService>(bool singleton)
{
return ServiceLocator.Current.GetInstance<TService>(singleton ? null : Guid.NewGuid().ToString());
}