2012-12-06 69 views
9

我有一個MVVM Light Toolkit支持的WPF應用程序。該應用程序有以下情況。 該應用程序有兩種數據連接模式。一個是WCF服務另一個是直接數據庫。應用程序應通過上述模式之一連接到數據庫。連接模式選擇位於登錄窗口中。最終用戶可以選擇其中一種連接模式(WCF服務或直接數據庫),並根據該選擇在組合框中加載連接配置列表。 (請查看附加圖片瞭解更多信息)。連接配置位於本地xml配置文件中。另外,如果選擇了任何連接配置,則我應該分配一個默認連接配置。MVVMLight簡單的IOC - 動態註冊和取消註冊數據服務實現

enter image description here

在視圖模型定位,我註冊的默認服務如下

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

兩個與dbclient和DataServiceClient實施IDataservice

如果已經在配置文件中指定了默認連接,當視圖模型定位器在應用程序啓動時註冊視圖模型時,上述代碼可以正常工作.IDataservice使用默認連接配置註冊。

現在真正的問題是,當用戶選擇連接配置時,該連接配置成爲默認連接配置,我希望MVVM Light註銷以前的數據服務並註冊新選擇的服務,並使用它連接到數據。

我嘗試下面的代碼在點擊登錄按鈕,但失敗:(

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 
} 

更新的代碼

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

上面的代碼中'ICometDataService'和'IDataService'有什麼區別? – tcarvin

+0

@tcarvin - 實際上它是IDataService。 – Dennis

回答

1

我會簡單地刪除:

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; 
        } 
       } 
您的ViewModelLocator中的

並將SignInButtonClick中的代碼更改爲:

void SignInButtonClick() 
{ 

    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 
} 

通過這樣做,您只需註冊一次服務,並且可以保證您註冊了正確的界面。

+0

我做到了。但是它會在ViewModelLocator中實例化Login View Model屬性時引發錯誤。異常詳細信息如下 - 「調用的目標引發了異常」。內部異常 - 在緩存中找不到類型:DataService.IDataService。「 – Dennis

+0

您可以發佈您的登錄視圖模型的代碼嗎?我懷疑問題存在可能是因爲你試圖取消註冊你當前正在使用的類 –

+0

我的LoginViewModel沒有任何默認構造函數,所以我添加了一個。然後上面提到的異常已經消失了。目前LoginViewModel有兩個構造函數Default一個和參數化one.While註冊LoginViewModel(SimpleIoc.Default。註冊();),我有以下異常:「無法註冊:在LoginViewModel中找到多個構造函數,但沒有標記爲PreferredConstructor。」。我已經在問題本身中添加了更新的代碼塊。請看看。 – Dennis