【问题标题】:ServiceLocationProvider must be set必须设置 ServiceLocationProvider
【发布时间】:2015-01-20 10:56:03
【问题描述】:

我正在使用 MVVM Light。当我在我的资源中添加更多价值转换器时,我的应用程序崩溃并出现异常:

Microsoft.Practices.ServiceLocation.DLL 中出现“System.InvalidOperationException”类型的异常,但未在用户代码中处理

附加信息:必须设置 ServiceLocationProvider。

App.xaml.cs OnLaunched 事件中我有这行

ServiceLocator.Current.GetInstance<MyViewModel>();

它在那里崩溃.. 在这个 ServiceLocator 中,我可以看到有一个 SetLocatorProvider 方法,它以 ServiceLocatorProvider 为参数。我在 Web 上找不到任何内容,并且 Microsoft 的 MSDN 页面已过时:

protected override async void OnLaunched(LaunchActivatedEventArgs e)
    {
        Frame rootFrame = Window.Current.Content as Frame;

        if (rootFrame == null)
        {
            ...
        }

        if (rootFrame.Content == null)
        {
            ...
        }

        Window.Current.Activate();

        DispatcherHelper.Initialize();

        ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);

        ServiceLocator.Current.GetInstance<MyViewModel>();
    }

编辑:这是完整的 OnLaunched 事件。 放好后

ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);

发生异常:

在 GalaSoft.MvvmLight.Extras.DLL 中发生 Microsoft.Practices.ServiceLocation.ActivationException' 类型的异常,但未在用户代码中处理

附加信息:在缓存中找不到类型:cMC.ViewModel.MyViewModel。

这是 ViewModelLocator 的代码

public class ViewModelLocator
{
    public ViewModelLocator()
    {
        ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);

        SimpleIoc.Default.Register<MyViewModel>();
    }

    public MyViewModel MyVM
    {
        get
        {
            return ServiceLocator.Current.GetInstance<MyViewModel>();
        }
    }

    public static void Cleanup() {}
}

【问题讨论】:

  • 由于 ServiceLocator 是诸如 unity 或 mef 等可用 IoC 容器的某种包装器...它需要您通过调用方法 ServiceLocator.SetLocatorProvider(() => new UnityServiceLocatorAdapter(容器));

标签: c# .net xaml windows-phone-8.1 mvvm-light


【解决方案1】:

我想通了。

还需要注册 ViewModel,这发生在 ViewModelLocator 构造函数中,但由于某种原因,构造函数稍后执行。所以我像这样修改了 ViewModelLocator 类:

public class ViewModelLocator
{
    public ViewModelLocator()
    {

    }

    public static void SetAndReg()
    {
        ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);

        SimpleIoc.Default.Register<MyViewModel>();
    }

    public MyViewModel MyVM
    {
        get
        {
            return ServiceLocator.Current.GetInstance<MyViewModel>();
        }
    }

    public static void Cleanup() {}
}

}

然后在 App.xaml.cs 中:

...OnLaunched(...)
{
...
        DispatcherHelper.Initialize();

        ViewModelLocator.SetAndReg();

        ServiceLocator.Current.GetInstance<MyViewModel>();
...
}

【讨论】:

  • 抱歉没有看到这个错误。也许您可能会考虑不使用 SetAndReg 方法而是使用静态构造函数?请参阅上面的示例,然后您可以在 App.xaml 中实例化这个东西并在您的控件中使用它: DataContext="{Binding Source={StaticResource ViewModelLocator}, Path=TestButlerMainWindowViewModel}" 这应该是“更干净”
  • 感谢您的建议
  • 可能发生的情况是尚未创建视图模型定位器构造函数。因此,不会设置服务定位器。尝试在不同的事件(例如 OnWindowCreated)中使用您的原始代码,看看是否能解决您的问题。如果您想要所有启动事件,请查看此链接:msdn.microsoft.com/en-us/library/ie/…
【解决方案2】:

你没有设置 LocationProvider(错误信息很明显..):

您需要为 ServiceLocator 提供您选择的 IoC 容器: 请参阅这个使用 Unity 和适配器的示例:

static ViewModelLocator()
    {
        var container = new UnityContainer();
        ServiceLocator.SetLocatorProvider(() => new UnityServiceLocatorAdapter(container));

        container.RegisterInstance<ILoggingService>(new ConsoleLoggingService());
        container.RegisterInstance<IMessageBoxService>(new SimpleMessageBoxService());
        container.RegisterInstance<ITestSuiteService>(new TestSuiteService());
        container.RegisterInstance<IApplicationService>(new ApplicationService());
    }

    /// <summary>
    /// Gets the <see cref="BackstageAboutViewModel"/>.
    /// </summary>
    public BackstageAboutViewModel BackstageAboutViewModel
    {
        get
        {
            return ServiceLocator.Current.GetInstance<BackstageAboutViewModel>();
        }
    }

【讨论】:

  • 在构造函数 ViewModelLocator 中有一行:“ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);”。不是这个吗?当我在 App.cs 的 OnLaunched 事件中复制它时,它会发出一个异常,告诉我在缓存中找不到 MyViewModel ..
  • @V.G.你应该提供比我期望你不设置任何东西更多的代码。
  • @V.G.从我的角度来看,您的代码看起来不错。如果您没有修改 SimpleIoC 或其他东西,我猜您的问题出在其他地方。您现在发布此错误消息:在缓存中找不到类型:cMC.ViewModel.MyViewModel。这表明,您的 TYPE MyViewModel 有点无法解决,您那里有一些依赖项吗?
  • 我不这么认为。我创建了一个新的干净项目,模拟了同样的问题,并且这个带有缓存的东西仍然指向 ViewModel..
猜你喜欢
  • 2021-09-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-02
  • 2018-01-03
  • 2010-12-27
  • 1970-01-01
相关资源
最近更新 更多