webentwicklung-frage-antwort-db.com.de

ServiceLocationProvider muss gesetzt sein

Ich verwende MVVM Light. Wenn ich in meinen Ressourcen mehr Wertkonverter hinzufüge, stürzt meine App mit Ausnahme ab:

Eine Ausnahme des Typs 'System.InvalidOperationException' ist in Microsoft.Practices.ServiceLocation.DLL aufgetreten, wurde jedoch nicht im Benutzercode behandelt

Zusätzliche Informationen: ServiceLocationProvider muss gesetzt sein.

Im Ereignis App.xaml.cs OnLaunched habe ich diese Zeile

ServiceLocator.Current.GetInstance<MyViewModel>();

Dort stürzt es ab. In diesem ServiceLocator kann ich sehen, dass es eine SetLocatorProvider-Methode gibt, die als Argument ServiceLocatorProvider verwendet. Ich konnte nichts auf der MSDN-Seite für Web- und Microsofts-Produkte finden:

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

BEARBEITEN: Hier ist das vollständige OnLaunched-Ereignis. Nach dem Einfügen 

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

eine Ausnahme tritt auf:

Eine Ausnahme des Typs Microsoft.Practices.ServiceLocation.ActivationException 'ist in GalaSoft.MvvmLight.Extras.DLL aufgetreten, wurde jedoch nicht im Benutzercode behandelt

Zusätzliche Informationen: Typ im Cache nicht gefunden: cMC.ViewModel.MyViewModel.

Dies ist der Code von 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() {}
}
8
v.g.

Ich habe es irgendwie herausgefunden.

Das ViewModel musste auch registriert werden. Dies geschah im ViewModelLocator-Konstruktor. Aus irgendeinem Grund wird der Konstruktor jedoch später ausgeführt. Also habe ich die ViewModelLocator-Klasse folgendermaßen geändert:

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

}

Dann in der App.xaml.cs:

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

        ViewModelLocator.SetAndReg();

        ServiceLocator.Current.GetInstance<MyViewModel>();
...
}
5
v.g.

Sie legen den LocationProvider nicht fest (die Fehlermeldung ist ziemlich offensichtlich ..):

Sie müssen dem ServiceLocator Ihren IoC-Container Ihrer Wahl geben: Siehe dieses Beispiel, das Unity und einen Adapter verwendet:

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