2012-12-06 15 views
9

Ich habe eine WPF-Anwendung mit MVVM Light Toolkit-Unterstützung. Die Anwendung hat das folgende Szenario. Die Anwendung verfügt über zwei Datenverbindungsmodi. Einer ist WCF-Dienst und der andere ist Direkte Datenbank. Die Anwendung sollte über einen der oben genannten Modi eine Verbindung zur Datenbank herstellen. Die Verbindungsmodusauswahl befindet sich im Anmeldefenster. Der Endbenutzer kann einen der Verbindungsmodi auswählen (WCF-Dienst oder direkte Datenbank), und basierend auf dieser Auswahl wird eine Liste der Verbindungskonfigurationen in das Kombinationsfeld geladen. (Bitte überprüfen Sie das angehängte Bild für weitere Informationen). Die Verbindungskonfigurationen befinden sich in einer lokalen XML-Konfigurationsdatei. Außerdem habe ich eine Standardverbindungskonfiguration, die zugewiesen werden sollte, wenn eine der Verbindungskonfigurationen ausgewählt ist.MVVMLight Simple IOC - dynamisch registrieren und die Registrierung von Datendienst-Implementierungen aufheben

enter image description here

Im Ansicht Modell Locator, ich bin Registrierung den Standarddienst als

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

      if (ViewModelBase.IsInDesignModeStatic) 
      { 
       // Create design time view services and models 
       if (!SimpleIoc.Default.IsRegistered<IDataService>()) 
        SimpleIoc.Default.Register<IDataService, MockDataClient>(); 
      } 
      else 
      { 
       // Create run time view services and models 
       if (!SimpleIoc.Default.IsRegistered<IDataService>()) 
       { 
        switch (DefaultConnectionConfiguration.ConnectionMode) 
        { 
         case DataConnectionMode.WcfService: 
          var wcfServiceConfiguration = (WcfServiceConfiguration)CurrentConnectionConfiguration; 
          SimpleIoc.Default.Register<IDataService>(
           () => 
           wcfServiceConfiguration != null 
            ? new DataServiceClient("WSHttpBinding_IDataService", 
                   wcfServiceConfiguration.EndpointUrl) 
            : null); 
          break; 

         case DataConnectionMode.Database: 
          SimpleIoc.Default.Register<IDataService, DbClient>(); 
          break; 
        } 
       } 

      } 
     SimpleIoc.Default.Register<LoginViewModel>(); 
     SimpleIoc.Default.Register<ManageConfigurationsViewModel>(); 

Beide dbclient und DataServiceClient implementieren IDataservice folgt.

Wenn bereits eine Standardverbindung in der Konfigurationsdatei angegeben ist, funktioniert der obige Code einwandfrei, wenn der Ansichtsmodell-Locator die Ansichtsmodelle bei der Anwendung start registriert. IDataservice ist mit der Standardverbindungskonfiguration registriert.

Jetzt ist das wirkliche Problem, wenn der Benutzer eine Verbindungskonfiguration auswählt, diese Verbindungskonfiguration die Standardverbindung wird und ich möchte, dass MVVM Light den vorherigen Datendienst auflistet und den neu ausgewählten registriert und mit ihm verbindet Daten.

Ich habe versucht, den folgenden Code in das Zeichen in Schaltfläche klicken und es ist fehlgeschlagen :(

void SignInButtonClick() 
{ 
     if(SimpleIoc.Default.IsRegistered<IDataService>()) 
            SimpleIoc.Default.Unregister<IDataService>(); 

    switch (DefaultConnectionConfiguration.ConnectionMode) 
          { 
           case DataConnectionMode.WcfService: 
            var wcfServiceConfiguration = (WcfServiceConfiguration)CurrentConnectionConfiguration; 
            SimpleIoc.Default.Register<IDataService>(
             () => 
             wcfServiceConfiguration != null 
              ? new DataServiceClient("WSHttpBinding_IDataService", 
                     wcfServiceConfiguration.EndpointUrl) 
              : null); 
            break; 

           case DataConnectionMode.Database: 
            SimpleIoc.Default.Register<IDataService, DbClient>(); 
            break; 
          } 
//perform authentication process 
} 

Aktualisiert-Code

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

      if (ViewModelBase.IsInDesignModeStatic) 
      { 
       // Create design time view services and models 
       if (!SimpleIoc.Default.IsRegistered<IDataService>()) 
        SimpleIoc.Default.Register<IDataService, MockDataClient>(); 
      } 
      SimpleIoc.Default.Register<LoginViewModel>(); 
     } 

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

     public static void Cleanup() 
     { 
      // TODO Clear the ViewModels 
      ServiceLocator.Current.GetInstance<LoginViewModel>().Cleanup(); 
     } 
    } 



public class LoginViewModel : ViewModelBase 
    { 
     ICometDataService service; 

    #region Constructor 
     public LoginViewModel() 
     { 

     } 
     public LoginViewModel(IDataService dataService) 
      : base(dataService) 
     { 
      service = dataService; 
     } 

     #endregion 
} 
+0

Was ist der Unterschied zwischen 'ICometDataService' und' IDataService' in Ihrem obigen Code? – tcarvin

+0

@tcarvin - Eigentlich ist es IDataService. – Dennis

Antwort

1

ich einfach entfernen würde:

if (!SimpleIoc.Default.IsRegistered<IDataService>()) 
       { 
        switch (DefaultConnectionConfiguration.ConnectionMode) 
        { 
         case DataConnectionMode.WcfService: 
          var wcfServiceConfiguration = (WcfServiceConfiguration)CurrentConnectionConfiguration; 
          SimpleIoc.Default.Register<IDataService>(
           () => 
           wcfServiceConfiguration != null 
            ? new DataServiceClient("WSHttpBinding_IDataService", 
                   wcfServiceConfiguration.EndpointUrl) 
            : null); 
          break; 

         case DataConnectionMode.Database: 
          SimpleIoc.Default.Register<IDataService, DbClient>(); 
          break; 
        } 
       } 

von Ihrem ViewModelLocator und ändern Sie den Code in SignInButtonClick zu:

Dadurch müssen Sie Ihren Dienst nur einmal registrieren und Sie können garantieren, dass Sie die richtige Schnittstelle registrieren.

+0

tat ich. Bei der Instanziierung der Eigenschaft "Anmeldungsansichtsmodell" in ViewModelLocator wird jedoch ein Fehler ausgegeben. Die Ausnahmedetails sind wie folgt - "Ausnahme wurde durch das Ziel eines Aufrufs ausgelöst" .Inner Ausnahme - Typ nicht im Cache gefunden: DataService.IDataService. " – Dennis

+0

Können Sie den Code für Ihre Login-Ansicht Modell? Ich vermute das Problem möglicherweise, dass Sie versuchen, eine Klasse aufzuheben, die Sie gerade verwenden. –

+0

Mein LoginViewModel hat keinen Standardkonstruktor.So habe ich einen hinzugefügt.Dann ist die oben genannte Ausnahme verschwunden.Zurzeit haben LoginViewModel zwei Konstruktoren Default eine und parametrierte. Während der Registrierung des LoginViewModel (SimpleIoc.Default.Registrieren ();), ich habe die folgende Ausnahme: "Kann nicht registrieren: Mehrere Konstruktoren in LoginViewModel, aber keine mit PreferredConstructor markiert.". Ich habe den aktualisierten Codeblock in der Frage selbst hinzugefügt. Bitte schauen Sie es sich an. – Dennis