静态构造函数之前的异步加载设置

时间:2014-01-28 00:05:50

标签: c# mvvm windows-8 windows-runtime mvvm-light

我刚刚完成了我的新应用,但是我被卡住了。我的应用程序分为两部分 - 远程和本地。我需要的是根据一些异步反序列化的应用程序设置为接口注册一个类。这是'想法代码'

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

        // It can't work :(((
        if(await SettingsManager.LoadSettings().EnableRemote) // <<<<<<
        {
            SimpleIoc.Default.Register<IMyService, MyRemoteService>();
        }
        else
        {
            SimpleIoc.Default.Register<IMyService, MyLocalService>();
        }

        SimpleIoc.Default.Register<MainViewModel>();
        SimpleIoc.Default.Register<SomeOtherViewModel>();
    }

我该怎么解决?这些设置在我的WinRT应用程序的隔离存储中的XML文件中序列化。拜托,你能想到任何建议吗?

1 个答案:

答案 0 :(得分:3)

它打破了IoC模式以异步注册绑定。您需要将异步设置合并到包装类中。这个包装类应该负责:

  1. 加载设置
  2. 提供IMyService
  3. 的实际实施

    如果IMyService具有同步方法,那么您可能需要更改它,要么提供所有方法的异步版本,要么提供Ready属性+事件,以便消费者将知道什么时候可以安全访问。但如果它是一项服务,它的方法可能已经是异步的,对吧?

    作为一个例子,让我们调用包装类MyServiceWrapper。它将在首次构建时加载设置,并通过IMyService中的所有异步方法(例如,SomeMethodAsync,如下所示)。

    public interface IMyService
    {
        Task SomeMethodAsync(Action<bool> callback);
    }
    
    public class MyServiceWrapper : IMyService
    {
        private IMyService _impl = null;
        private IMyService _remote, _local;
        private bool _loaded = false;
        private object _sync = new object();
    
        public Task SomeMethodAsync(Action<bool> callback)
        {
            // first make sure the settings have been loaded
            await LoadSettings();
            _impl.SomeMethodAsync(callback);
        }
    
        public MyServiceWrapper(MyRemoteService remoteService, MyLocalService localService)
        {
            _remote = remoteService;
            _local = localService;
            LoadSettings();
        }
    
        private async Task<bool> LoadSettings()
        {
            if (_loaded)
                return true;
            // lock to prevent multiple threads from loading the settings
            lock (_sync)
            {
                if (_loaded)
                    return true;
    
                if(await SettingsManager.LoadSettings().EnableRemote)
                    _impl = _remote;
                else
                    _impl = _local;
            }
            return true;
        }
    }
    

    现在你可以让你的DI容器注册:

    • MyRemoteService - &gt; MyRemoteService
    • MyLocalService - &gt; MyLocalService
    • IMyService - &gt; MyServiceWrapper