MVVM Light Locator:注册ViewModelBase的所有派生

时间:2016-12-07 22:44:00

标签: c# .net wpf mvvm mvvm-light

这是我的定位器。出于演示目的,我剥离了除两个之外的所有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();
        }
    }
}

1 个答案:

答案 0 :(得分:0)

通常情况下,制定一个正确的问题需要我深入挖掘,所以一段时间后我想出了ViewModelLocator构造函数的代码。我想分享一下,因为我觉得这至少是有点常见的MVVM Light问题,我还没有找到任何解决方案。

  • 首先,从所有程序集中检索所有类型的ViewModelBase
  • 然后,我们需要获得Register SimpleIoc方法。现在,我没有比找到&#34;找到&#34;更好的主意。它使用.Where请随时改进此声明!
  • 最后,我将MakeGenericMethodViewModelBase衍生物的类型一起使用。
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());
}