gpt4 book ai didi

c# - MVVMLight 和平台特定的服务实现

转载 作者:太空狗 更新时间:2023-10-29 22:00:36 24 4
gpt4 key购买 nike

我有什么

使用 MVVMLight,我有一些在可移植项目中声明的服务接口(interface)以及在 Windows Phone 项目 (WP8.1 SL) 中的相应实现。为了注册实现,我在 App 类的 Application_Launching 方法中使用了 SimpleIoc.Default.Register

public partial class App : Application
{
...

private async void Application_Launching(object sender, LaunchingEventArgs e)
{
...

// add some platform specific services to the IOC container
SimpleIoc.Default.Register<INavigationService, NavigationServiceWP>(true);
SimpleIoc.Default.Register<ISettingsService, SettingsService>(true);
SimpleIoc.Default.Register<IThemeService, ThemeService>(true);
SimpleIoc.Default.Register<IGeofenceService, GeofenceService>(true);
SimpleIoc.Default.Register<IVersionService, TrialInformation>(true);
SimpleIoc.Default.Register<IPhoneService, PhoneServices>(true);

...
}

...
}

View 模型定位器位于可移植项目中,并将所有 View 模型注册到静态构造函数中的 IOC 容器,正如文档所说。

static ViewModelLocator()
{
...

SimpleIoc.Default.Register<TagColorViewModel>();

...
}

TagColorViewModel 是这些模型之一。它会在显示相应 View 之前收到一条消息。例如,当单击标签更改其颜色时,将使用 MessengerInstance.Send,然后使用导航服务导航至标签颜色更改 View 。

// TagViewModel
private void ChangeColor()
{
MessengerInstance.Send(Tag, TagColorViewModel.MessengerToken.SetTag);
_navigationService.Navigate("/UI/Tagging/TagColor.xaml");
}

这个消息接收者在构造函数中注册。

// TagColorViewModel
[PreferredConstructor]
public TagColorViewModel(INavigationService navigationService)
{
...

// Messages
MessengerInstance.Register<Tag>(this, MessengerToken.SetTag, SetTag);
}

实际问题

因为 View 模型是在 MVVMLight 中创建的,就在它通过相应的 View 第一次被使用之前,TagColorViewModel 没有收到消息(仅仅是因为还没有那个 VM 的实例).

一个可能的解决方案是在注册 View 模型时使用 true 作为参数。

SimpleIoc.Default.Register<TagColorViewModel>(true);

不幸的是,这不起作用。原因是,从上面的构造函数中可以看出,TagColorViewModel 依赖于 INavigationService。这又在 Application_Launching 方法中注册,该方法在调用 View 模型定位器的静态构造函数之后。结果是 SimpleIoc 无法创建 TagColorViewModel 的实例,因为没有已知的 INavigationService 接口(interface)或实现。

真题

我该如何解决这个问题?换句话说:我如何在 MVVMLights SimpleIoc 中注册特定于平台的服务,以便我可以让它在注册期间创建 View 模型的实例?

Xamarin 似乎使用装饰器来解决此类问题,但我不知道 MVVMLight 中有任何类似的结构。

Xamarin.Forms.Dependency(typeof(PopupService))

当前的解决方法

我目前的解决方法是在注册所有特定于平台的服务后立即获取一个以后永远不会使用的实例。它有效,但我认为这不是正确的解决方案。

private async void Application_Launching(object sender, LaunchingEventArgs e)
{
...

// add some platform specific services to the IOC container
SimpleIoc.Default.Register<INavigationService, NavigationServiceWP>(true);
...

var tcvm = SimpleIoc.Default.GetInstance<TagColorViewModel>();

...
}

最佳答案

结合使用 Xamarin 的依赖服务和 MVVMLight。 MVVMLight 的 Register 方法有一个重载,您可以在其中编写自己的函数来生成实例。

像这样将所有服务注册放回 ViewModelLocator:

SimpleIoc.Default.Register<Service.INavigationService>(() => {
return DependencyService.Get<Service.INavigationService>();
});

然后将适当的程序集属性放在特定于平台的服务实现上...

[assembly: Xamarin.Forms.Dependency(typeof(NavigationService))]

关于c# - MVVMLight 和平台特定的服务实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30446328/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com