【问题标题】:DryIoc and IServiceProvider on Prism for Xamarin.Forms (DryIoc.Microsoft.DependencyInjection)Prism 上的 DryIoc 和 IServiceProvider 用于 Xamarin.Forms (DryIoc.Microsoft.DependencyInjection)
【发布时间】:2020-05-21 12:20:21
【问题描述】:

我有一个以 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.
    }
}

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

public partial class App

// ...

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

那是在尝试使用IHttpClientFactory之前。

现在,要添加它,我们 should 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);
}

问题在于,在我的 ExampleService 中,我得到了具有以下规格的 client

{
   "DefaultRequestHeaders":[
   ],
   "BaseAddress":null,
   "Timeout":"00:01:40",
   "MaxResponseContentBufferSize":2147483647
}

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

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

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

更新 #1

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

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;
}

并且containerRegistry.Register&lt;IExampleService, ExampleService&gt;(); 已从 RegisterTypes() 中删除。

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

更新 #2

我使用的与 Prism 相关的唯一软件包是 Prism.DryIoc.FormsPrism.DryIoc.Extensions。 我完全删除了 App.xaml.csCreateContainerExtension() 的覆盖,并将 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/");
        });
    });
}  

这样我会得到一个NotImplementedException
但是,通过使用以下内容覆盖 CreateContainerExtension()

protected override IContainerExtension CreateContainerExtension() => PrismContainerExtension.Current;  

一切终于恢复正常!

【问题讨论】:

    标签: xamarin.forms prism


    【解决方案1】:

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

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

    protected override IContainerExtension CreateContainerExtension() =>
        PrismContainerExtension.Current;
    

    【讨论】:

    • 非常清楚,您不会使用 Prism.DryIoc.Forms.Extended,因为它已被弃用。您需要为您想要的容器安装 Prism.Forms.Extended 和 Extensions 包。它会自动连接起来,你不需要做任何与普通 Prism 应用程序不同的事情。
    • @YanKarin 关闭但摆脱 CreateContainerExtension... 您的注册应该与 RegisterTypes 方法中的 ContainerRegistry 以及您正在注册的任何其他内容一起使用。
    • 您不应该将 Prism.DryIoc.Forms 与 Prism.DryIoc.Extensions 一起使用。要么使用 Prism.Forms 保持代码原样,要么停止尝试覆盖 CreateContainerExtension 并使用 Prism.Forms.Extended 和 Prism.DryIoc.Extensions
    • 如果我尝试使用 Prism.Forms 和 Prism.DryIoc.Extensions,则无法找到 PrismApplication,因为它不包含在 Prism.Forms 包中。你确定我不应该使用 Prism.DryIoc.Forms 吗?如果不想使用 Prism.Forms.Extended,我认为这是拥有 PrismApplication 的唯一方法。
    • 如果您使用的是 Prism.Forms 而不是 Prism.Forms.Extended,则需要从 PrismApplicationBase 继承。 CreateContainerExtension 是 PrismApplication 在容器特定包中实现的唯一内容。由于您使用的是 Prism.DryIoc.Extensions,因此您不应该同时引用 Prism.DryIoc.Forms。希望能为您解决问题。
    【解决方案2】:

    添加因为这是我在数周的搜索中发现的唯一一篇解释如何执行此操作的帖子。

    我使用的是 Unity 而不是 Dryloc,但解决方案是一样的。

    安装这些附加软件包:

    Prism.Forms.Extended

    Prism.Unity.Extensions

    protected override void RegisterTypes(IContainerRegistry containerRegistry)
    {
        //Omitted Code
    
        containerRegistry.RegisterServices(serviceCollection =>
        {
            serviceCollection.AddHttpClient<IApiService, ApiService>(client =>
            {
                client.BaseAddress = new Uri("Your Address Here");
            });
        });
    }
    
    public ApiService(HttpClient client)
    {
        //Do Stuff
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-09-28
      • 2022-12-22
      • 2019-10-06
      • 2021-07-01
      • 2018-07-14
      • 2019-04-07
      • 1970-01-01
      相关资源
      最近更新 更多