如何在 Prism 应用程序中手动解析类型时获取正确的 INavigationService 实例

Chr*_*ett 5 c# dependency-injection prism xamarin xamarin.forms

似乎当我手动解析一个类型并请求INavigationService其中注入一个与其他地方使用的实例不同的实例时。

为了澄清我的用例,这里摘录了相关文件。正如您所看到的,在解析类型时SampleProcessINavigationService被注入,但实例与我获得的实例不同ProcessService。(顺便说一句,这是正确的实例,可以用于导航。注入的实例SampleProcess不能用于导航。)

任何想法为什么会发生这种情况,更重要的是我如何获得正确的实例INavigationService注入SampleProcess。是的,我可以通过使用方法传递它来提供它,但这并不是那么漂亮。

应用程序.xaml.cs

protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
    containerRegistry.RegisterSingleton<ProcessService>();
    containerRegistry.Register<Processes.SampleProcess>();
}
Run Code Online (Sandbox Code Playgroud)

流程服务.cs

public class ProcessService
{
    private readonly IContainer container;
    private readonly INavigationService navigationService;

    public ProcessService(IContainer container, INavigationService navigationService)
    {
        this.container = container;
        this.navigationService = navigationService;
    }

    public void ExecuteProcess(ProcessEnum processEnumValue)
    {
        Type processType = processEnumValue switch
        {
            ProcessEnum.SampleProcess => typeof(Processes.SampleProcess),
            _ => throw new NotImplementedException()
        };

        var process = App.Current.Container.Resolve(processType) as IProcess;

        bool test = process.CheckNavigationService(navigationService); // will return false
    }
}
Run Code Online (Sandbox Code Playgroud)

示例进程.cs

public class SampleProcess : IProcess
{
    private readonly INavigationService navigationService;

    public SampleProcess(INavigationService navigationService)
    {
        this.navigationService = navigationService;
    }

    public bool CheckNavigationService(INavigationService navigationService)
    {
        return this.navigationService == navigationService;
    }
}
Run Code Online (Sandbox Code Playgroud)

Chr*_*ett 0

我通过向从视图模型中调用的方法添加一个INavigationService参数来解决这个问题ExecuteProcess(实际上有正确的INavigationService实例)。在该方法中,我通过执行以下操作来解决该过程:

var process = container.Resolve(processType, new[] { navigationService }) as IProcess;
Run Code Online (Sandbox Code Playgroud)

这样,实例INavigationService中就可以使用正确的实例IProcess

正如 @Dan Siegel 所说,通过使用 Prism 8 并将 注册为范围服务,可以进一步改进这一点,ProcessService因为这将消除INavigationServiceExecuteProcess.