在 ReactiveUI 中,如何为 MutableDependencyResolver 调用 GetService

In ReactiveUI, how to call GetService for MutableDependencyResolver

我正在阅读《你、我和 ReactiveUI》这本书,我的问题与 https://github.com/kentcb/YouIandReactiveUI 上的这本书的源代码有关。 ReactiveUI 和 Splat 的版本在代码发布后发生了变化,其中一部分代码无法在当前版本中复制。我已经联系了作者,在发布这个问题的时候还在等待回复,所以我在这里提交这个问题。

在 App.xaml.cs 中有一个对 Registrations.cs class 的调用,它传递了当前的可变依赖解析器:

public App()
{
    this.autoSuspendHelper = new AutoSuspendHelper(this);
    Registrations.Register(Splat.Locator.CurrentMutable);
}

在 Registrations.cs class 中,有一行采用 IMutableDependencyResolver 并调用 GetService:

public static void Register(IMutableDependencyResolver container)
{
    ...

    var defaultViewLocator = container.GetService<IViewLocator>();

    ...
}

我也想获得 IVewLocator 服务,但 IMutableDependencyResolver 不再有 GetService 方法。

所以我的问题是,应该如何修改此代码以具有相同的功能?

Splat.Locator.Current 是一个 IReadonlyDependenyResolver,它有一个 GetService 方法。应该改用它吗?我不确定我是否应该改为使用 Splat.Locator.Current 以防万一使用 Splat.Locator.CurrentMutable 是有原因的,我想确保如果我改为使用 Splat.Locator.Current 它会不要引入任何意外。

更新:

只是想补充一点,从 DPVreony 的回答中了解到这两个接口的实现通常是相同的 class,我能够在 Registrations.cs class 我需要的。

因此,进一步 class,有一些行注册常量。这些需要可变的依赖解析器。所以你可以将只读和可变的都传递给注册 class 并在需要的地方使用它们,如下所示:

public static void Register(IReadonlyDependencyResolver container, IMutableDependencyResolver mutableContainer)
{

    ...

    var defaultViewLocator = container.GetService<IViewLocator>();

    ...

    mutableContainer.RegisterConstant(viewLocator, typeof(IViewLocator));

    ...

    var defaultActivationForViewFetcher = container.GetService<IActivationForViewFetcher>();
       
    ...
        
    mutableContainer.RegisterConstant(activationForViewFetcher, typeof(IActivationForViewFetcher));
    mutableContainer.RegisterConstant(activationForViewFetcher, typeof(IForcibleActivationForViewFetcher));
}

然后像这样调用方法:

Registrations.Register(Splat.Locator.Current, Splat.Locator.CurrentMutable);

由于某些 DI 容器在注册服务时的行为方式(即它们不断重新初始化),Splat 发生了变化。因此,获取功能被拆分到 Splat.Locator.Current

公开的 IReadonlyDependenyResolver 上

这是为了鼓励使用 MutableLocator 将所有内容都放置到位,然后您只需要使用 Splat.Locator.Current 进行阅读,这样您就可以使用它了。通常它是相同的 class 实现 2 个接口,因此这是一个语义更改,以减少错误地拆除定位器的风险。

所以简而言之,Splat.Locator.Current 用于 GetService

希望一切都有意义。