如何在 Xamarin Forms 中实现/注册单例 HttClientFactory

How to implement / register singleton HttClientFactory in Xamarin Forms

我在 Prism 中使用 Xamarin Forms。

如何为 HttpClientFactory 注册服务? xamarin/prism 中是否有与 .net core 中的 ConfigureServices 方法等效的方法?

我想在 Xamarin 表单中使用与此代码等效的代码:

    services.AddHttpClient<MyClient>("MyHttpClient",
        x => { x.BaseAddress = new Uri("example.com"); }
        ).AddPolicyHandler(GetRetryPolicy());
    services.AddSingleton<MyClientFactory>();

我一直在尝试不同的方法,但找不到正确的方法。

非常感谢。

更新

我在名为 BusinessLogic

的网络标准类库中获得了这些类

MyClientFactory.cs:

namespace BusinessLogic.Services
{
    public class MyClientFactory
    {
        private readonly IServiceProvider _serviceProvider;

        public MyClientFactory(IServiceProvider serviceProvider)
        {
            _serviceProvider = serviceProvider;
        }

        public MyClient Create()
        {
            return _serviceProvider.GetRequiredService<MyClient>();
        }
    }
}

MyClient.cs:

namespace ServiceBusinessLogic.Services
{
    public class MyClient : IMyClient
    {
        private readonly HttpClient _httpClient;
        private readonly ILogger<MyClient> _logger;

        public MyClient(ILogger<MyClient> logger, HttpClient httpClient)
        {
            _logger = logger;
            _httpClient = httpClient ?? throw new ArgumentNullException(nameof(httpClient));
        }

        public async Task<Result<Token>> GetToken(CancellationToken cancellationToken, string userName, string password)
        {
            try
            {
                HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "Token");
                request.Content = new FormUrlEncodedContent(new[]
                {
                    new KeyValuePair<string, string>("grant_type", "password"),
                    new KeyValuePair<string, string>("username", userName),
                    new KeyValuePair<string, string>("password", password)
                });

                HttpResponseMessage result = await _httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
                if (!result.IsSuccessStatusCode)
                {
                    _logger.LogError("the status code is: {0}", (int)result.StatusCode);

// CODE abbreviated for reading

        }

接口一MyClient.cs:

namespace MyBusinessLogic.Services
{
    public interface IMyClient
    {
        Task<Result<Token>> GetToken(CancellationToken cancellationToken, string userName, string password);
    // CODE abbreviated for reading

MyClientQueries.cs:

namespace MyBusinessLogic.Services
{
    public class MyClientQueries
    {
        private readonly MyClientFactory _myClientFactory;

        public MyClientQueries(MyClientFactory myClientFactory)
        {
            _MyClientFactory = myClientFactory ?? throw new ArgumentNullException(nameof(myClientFactory));

        }

        public async Task<Result<Token>> GetToken(CancellationToken cancellationToken, string username, string password)
        {
            var mysClient = _myClientFactory.Create();
            var response = await tsClient.GetToken(cancellationToken, username, password).ConfigureAwait(true);

            return response;
        }
// CODE abbreviated

然后我得到了一个名为 App_Mobile_test

的带有 Prism 的 xamarin 表单项目

App.xaml.cs:

 public partial class App : PrismApplication
    {
         public App() : this(null) { }

        public App(IPlatformInitializer initializer) : base(initializer) { }

        protected override async void OnInitialized()
        {
            InitializeComponent();

            await NavigationService.NavigateAsync("NavigationPage/MainPage");
        }

        protected override void RegisterTypes(IContainerRegistry containerRegistry)
        {
            containerRegistry.RegisterForNavigation<NavigationPage>();
            containerRegistry.RegisterForNavigation<MainPage>();

        }
    }

我想使用 MyClientQueries,它将 DI 用于 HttpClientFactoryHttpClient Xamarin Forms 项目即服务(单例),因此我可以调用 GetToken 和其中的所有其他方法 class。

但我不知道如何在 Xamarin Forms 中执行此操作。

包含我要使用的 MyClientQueries 的 MyBusinessProject 已经在 asp.net 核心 mvc 中使用,并且服务已添加到 .net 核心中的 startup.cs 中,如下所示:

public void ConfigureServices(IServiceCollection services)
{
#region "api service"  

            services.AddSingleton<MyClientQueries>();

            services.AddHttpClient<MyClient>("MyHttpClient", 
                x => { x.BaseAddress = new Uri(Configuration["APIConfiguration:BaseAddress"]); }
                ).AddPolicyHandler(GetRetryPolicy());

            services.AddSingleton<MyClientFactory>();

            #endregion
//CODE abbreviated
}

如何注册我在 .net Core 应用程序中正在执行的相同对象,但在 Xamarin Forms 中,并为视图模型使用依赖项注入? 共享项目“MyBusinessLogic”在 asp.net 核心中运行良好,我想在 Xamarin 项目中重用该项目。特别是具有 HttpClientFactory 依赖项的 MyClientQueries。

语法是什么取决于您使用的是什么 DI,但通常这种代码会在 App 构造函数或构造函数调用的方法中。

例如,您的 App.xaml.cs 中可能有一个名为 RegisterServices 的方法,它是在调用 Xamarin Init() 之后从构造函数调用的。

在该 RegisterServices 方法中,您将拥有如下内容:

   FreshIOC.Container.Register<IHttpManager, HttpManager>().AsSingleton();

我们使用 FreshMvvm,它使用 TinyIOC 进行依赖注入,因此语法可能不同,但概念是相同的。