用于 Xamarin.Forms 的 Prism 上的 DryIoc 和 IServiceProvider (DryIoc.Microsoft.DependencyInjection)

Yan*_*rin 4 prism xamarin.forms

我有一个以 DryIoc 作为容器的 Prism 应用程序。我想向我的类型客户IHttpClientFactory提供HttpClients ,它们是这样的:

public class ExampleService : IExampleService
{
    private readonly HttpClient _httpClient;

    public RepoService(HttpClient client)
    {
        _httpClient = client;
    }

    public async Task<IEnumerable<string>> GetExamplesAsync()
    {
        // Code deleted for brevity.
    }
}
Run Code Online (Sandbox Code Playgroud)

App.xaml.cs 中,我注册了我的类型化客户端,以便它们可以使用以下内容注入到视图模型中:

public partial class App

// ...

protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
    // Code deleted for brevity.
    containerRegistry.Register<IExampleService, ExampleService>();
}
Run Code Online (Sandbox Code Playgroud)

那是在尝试使用IHttpClientFactory.

现在,要添加它,我们应该 AddHttpClient()IServiceCollection. 这就是我认为需要DryIoc.Microsoft.DependencyInjection 的地方,所以,仍然在App.xaml.cs 中,我写了以下内容:

public partial class App

// ...

protected override IContainerExtension CreateContainerExtension()
{
    var services = new ServiceCollection();

    services.AddHttpClient<IExampleService, ExampleService>(c =>
    {
        c.BaseAddress = new Uri("https://api.example.com/");
    });

    var container = new Container(CreateContainerRules())
        .WithDependencyInjectionAdapter(services);

    return new DryIocContainerExtension(container);
}
Run Code Online (Sandbox Code Playgroud)

问题是,在我的ExampleService 中,我获得了具有以下规格的客户端

{
   "DefaultRequestHeaders":[
   ],
   "BaseAddress":null,
   "Timeout":"00:01:40",
   "MaxResponseContentBufferSize":2147483647
}
Run Code Online (Sandbox Code Playgroud)

虽然我希望BaseAddresshttps://api.example.com/,但 REST API 调用失败。

IServiceProvider将 Prism 用于 Xamarin.Forms 和 DryIoc 时使用的正确模式是什么?不幸的是,没有关于以下问题的文档或开源代码,我有点迷茫。

谢谢你,祝你有美好的一天。

更新 #1

按照Dan S. 的指导,DryIoc.Microsoft.DependencyInjection被卸载,因此项目在尝试使用IServiceCollection依赖项之前恢复到其状态(在我的情况下,IHttpClientFactory),然后我安装了Prism.Forms.Extended和后来的Prism.DryIoc.Extensions .
之后CreateContainerExtension()App.xaml.cs变成了:

protected override IContainerExtension CreateContainerExtension()
{
    var containerExtension = PrismContainerExtension.Current;
    containerExtension.RegisterServices(s =>
    {
        s.AddHttpClient<IExampleService, ExampleService>(c =>
        {
            c.BaseAddress = new Uri("https://api.example.com/");
        });
    });
    return containerExtension;
}
Run Code Online (Sandbox Code Playgroud)

containerRegistry.Register<IExampleService, ExampleService>();RegisterTypes() 中删除。

现在ExampleService终于得到HttpClient注入,一切正常。

更新 #2

我使用的与Prism相关的唯一软件包是Prism.DryIoc.FormsPrism.DryIoc.Extensions。余完全除去的覆盖CreateContainerExtension()App.xaml.cs和重构RegisterTypes()

protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
    // Code deleted for brevity.
    containerRegistry.RegisterServices(s =>
    {
        s.AddHttpClient<IExampleService, ExampleService>(c =>
        {
            c.BaseAddress = new Uri("https://api.example.com/");
        });
    });
}  
Run Code Online (Sandbox Code Playgroud)

这样我就会被抛出一个NotImplementedException.
但是,通过使用以下内容覆盖CreateContainerExtension()

protected override IContainerExtension CreateContainerExtension() => PrismContainerExtension.Current;  
Run Code Online (Sandbox Code Playgroud)

一切终于恢复正常了!

Dan*_* S. 6

如果您想使用 IServiceCollection 扩展,例如AddHttpClient我建议您使用 Prism Container Extensions。在您的情况下,它将是Prism.DryIoc.Extensions。容器扩展提供了许多额外的支持,包括支持通过服务集合扩展注册服务。

您可以安装 Prism.Forms.Extended 并且一切正常,或者您可以按如下方式更新您的应用程序:

protected override IContainerExtension CreateContainerExtension() =>
    PrismContainerExtension.Current;
Run Code Online (Sandbox Code Playgroud)

  • 需要明确的是,您不会使用 Prism.DryIoc.Forms.Extended,因为它已被弃用。您需要为您想要的容器安装 Prism.Forms.Extended 和扩展包。它会自动连接,您不需要做任何与普通 Prism 应用程序不同的事情。 (2认同)
  • 如果您使用 Prism.Forms 而不是 Prism.Forms.Extended,则需要从 PrismApplicationBase 继承。CreateContainerExtension 是 PrismApplication 在容器特定包中实现的唯一内容。由于您正在使用 Prism.DryIoc.Extensions,因此您不应该引用 Prism.DryIoc.Forms。希望这能为您解决问题。 (2认同)