简体   繁体   中英

How to implement / register singleton HttClientFactory in Xamarin Forms

I am using Xamarin Forms with Prism.

How can I register a service for HttpClientFactory? Is there a equivalent in xamarin/prism to the ConfigureServices method in .net core?

I would like to use the equivalent of this code in Xamarin forms:

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

I have been trying different ways and I cannot find the right way to do it.

Thanks a lot.

UPDATE

I have got these clases in a netstandard ClassLibrary called 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

        }

Interface IMyClient.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

Then I have got a xamarin forms Project with Prism called App_Mobile_test

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>();

        }
    }

I would like to use MyClientQueries which uses DI for HttpClientFactory and HttpClient in the Xamarin Forms project as a service (singleton) so I can call GetToken and all the other methods that are in that class.

But I do not know how to do this in Xamarin Forms.

MyBusinessProject that contains MyClientQueries which I want to use, is already used in a asp.net core mvc and the services were added in the startup.cs in .net core like this:

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
}

How can I register the same objects I am doing in the .net Core app, but in Xamarin Forms and use the dependency injection for the view models? The shared project "MyBusinessLogic" works fine in the asp.net core, and I would like to reuse this project in the Xamarin project. Specially MyClientQueries which has got HttpClientFactory dependency.

It will depend on what DI you are using as to what the syntax will be, but generally that sort of code will be in the App constructor or a method called by the constructor.

So for example you might have a method called RegisterServices in your App.xaml.cs that is called from the constructor, after the Xamarin Init() has been called.

Inside that RegisterServices Method you would have something like this:

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

We use FreshMvvm which uses TinyIOC for Dependancy Injection, so the syntax may differ, but the concept will be the same.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM