12

I am using MVVM Light. When I add more value converters in my resources my app crashes with exception:

An exception of type 'System.InvalidOperationException' occurred in Microsoft.Practices.ServiceLocation.DLL but was not handled in user code

Additional information: ServiceLocationProvider must be set.

In the App.xaml.cs OnLaunched event I have this line

ServiceLocator.Current.GetInstance<MyViewModel>();

It crashes there.. In this ServiceLocator I can see there is a SetLocatorProvider method which takes as an argument ServiceLocatorProvider. I couldnt find anything in the Web and Microsofts MSDN page is dated:

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>();
    }

EDIT: Here is the full OnLaunched event. After putting

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

an exception occures:

An exception of type Microsoft.Practices.ServiceLocation.ActivationException' occurred in GalaSoft.MvvmLight.Extras.DLL but was not handled in user code

Additional information: Type not found in cache: cMC.ViewModel.MyViewModel.

This is the code of 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() {}
}
Community
  • 1
  • 1
v.g.
  • 1,076
  • 5
  • 19
  • 38
  • 1
    Since the ServiceLocator is some sort of Wrapper for the available IoC Containers like unity or mef ... It requires you to set the provider by invoking the method ServiceLocator.SetLocatorProvider(() => new UnityServiceLocatorAdapter(container)); – Xeun Jan 20 '15 at 10:58

2 Answers2

6

I kinda figured it out.

There was also a need to register the ViewModel, something that happened in the ViewModelLocator constructor, but for some reason the constructor is executed later. So I modified the ViewModelLocator class like this:

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() {}
}

}

Then in the App.xaml.cs:

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

        ViewModelLocator.SetAndReg();

        ServiceLocator.Current.GetInstance<MyViewModel>();
...
}
v.g.
  • 1,076
  • 5
  • 19
  • 38
  • 1
    Sorry did not see that blunder. Maybe you might consider not using a SetAndReg method but using a static Constructor? See my Example above, you can then instatiate this thing in you App.xaml and use it in your controls: DataContext="{Binding Source={StaticResource ViewModelLocator}, Path=TestButlerMainWindowViewModel}" This is supposed to be "cleaner" – Xeun Jan 20 '15 at 12:55
  • Likely what is happening is the view model locator constructor has yet to be created. So therefore the service locator would not be set. Try using your original code in a different event such as OnWindowCreated and see if that fixes your issue. If you want all of the start up events check out this link: https://msdn.microsoft.com/en-us/library/ie/windows.ui.xaml.application#events – joshwl2003 Jan 21 '15 at 13:46
1

You are not setting the LocationProvider (well the error message is quite obvious..):

You need to give the ServiceLocator your IoC Container of choice: See this example which uses Unity and an Adapter:

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>();
        }
    }
Xeun
  • 1,089
  • 1
  • 11
  • 20
  • Well in the constructor ViewModelLocator theres a line: "ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);". Isn't it this? When I copy this in the OnLaunched event in App.cs it booms with an exception telling me that MyViewModel is not found in cache.. – v.g. Jan 20 '15 at 11:40
  • @V.G. You should provide more code than, I was expecting you to not set anything. – Xeun Jan 20 '15 at 11:45
  • @V.G. your code looks fine from my side.If you did not modify SimpleIoC or something I guess your problem is somewhere else. YOu are posting this error message now: Type not found in cache: cMC.ViewModel.MyViewModel. Which indicates, that somewhat you TYpe MyViewModel cannot be resolved, are you having some Dependencies there? – Xeun Jan 20 '15 at 12:05
  • I don' t think so. I created a new clean project, simulating the same problem and the this thing with the cache still pointed to the ViewModel.. – v.g. Jan 20 '15 at 12:18