wpf MVVMLight Simple IOC - 动态注册和注销数据服务实现

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13738049/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 06:30:26  来源:igfitidea点击:

MVVMLight Simple IOC - dynamically register and unregister data service implementations

c#wpfdesign-patternsmvvmmvvm-light

提问by Dennis

I have a WPF application with MVVM Light Toolkit support. The application has the following scenario. The application has two Data connection modes. One is WCF serviceand the other is Direct Database. The application should connect to the Database through one of the above mentioned modes. The connection mode selection is situated in Login window. The end user can select one of the connection modes (WCF Service or Direct Database) and based on that selection a list of connection configurations are loaded in Combo box. (Please check the attached image for more information). The connection configurations are located in a local xml configuration file. Also I have a default connection configuration which should be assigned if any of the connection configurations is selected.

我有一个支持 MVVM Light Toolkit 的 WPF 应用程序。该应用程序具有以下场景。该应用程序有两种数据连接模式。一个是WCF 服务,另一个是Direct Database。应用程序应通过上述模式之一连接到数据库。连接模式选择位于登录窗口。最终用户可以选择一种连接模式(WCF 服务或直接数据库),并根据该选择在组合框中加载连接配置列表。(请查看附件图片了解更多信息)。连接配置位于本地 xml 配置文件中。此外,我还有一个默认连接配置,如果选择了任何连接配置,则应分配该配置。

enter image description here

在此处输入图片说明

In the View Model Locator, I am registering the default service as follows

在 View Model Locator 中,我注册了默认服务如下

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

Both DbClient and DataServiceClient implement IDataservice.

无论与dbclient和DataServiceClient实施IDataservice

If there is already a default connection specified in the configuration file, the above code works fine when the view model locator registers the view models at the application start.ie IDataservice is registered with the default connection configuration.

如果配置文件中已经指定了默认连接,当视图模型定位器在应用程序启动时注册视图模型时,上面的代码工作正常。即 IDataservice 使用默认连接配置注册。

Now the real issue is when the user selects a connection configuration, that connection configuration becomes the default one and i want the MVVM Light to unregister the previous data service and register the newly selected one, and use it to connect to the data.

现在真正的问题是当用户选择连接配置时,该连接配置成为默认配置,我希望 MVVM Light 取消注册以前的数据服务并注册新选择的服务,并使用它连接到数据。

I tried the following code in the sign in button click and it failed :(

我在登录按钮单击中尝试了以下代码,但失败了:(

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
}

Updated 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
}

采纳答案by Faster Solutions

I'd simply remove:

我只是删除:

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

from your ViewModelLocator and change the code in SignInButtonClick to:

从您的 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
}

By doing this you only have to register your service once and you can guarantee that you're registering the correct interface.

通过这样做,您只需注册您的服务一次,您就可以保证您注册的是正确的接口。