Maui: AddHttpClient and AddSingleton outside of CreateMauiApp

194 Views Asked by At

I'm migrating an app from Xamarin Forms using Prism and DryIoc to Maui and need to register a service and HttpClientFactory outside of the CreateMauiApp function (Reason being I don't know the endpint for the HttpClient at startup - it's retrived as part of another process once the app is loaded).

I could do this with Prism and DryIoc using Prism's ContainerLocator...

var containerRegistry = ContainerLocator.Current;

containerRegistry.RegisterSingleton<IApiManager, ApiManager>();

containerRegistry.RegisterServices(serviceCollection =>
{
    serviceCollection.AddHttpClient<IApiService, ApiService>(client =>
    {
        client.BaseAddress = new Uri(uri);
    }
});

...but there is no way to register new services using IServiceProvider.

Anybody have any ideas about how to accomplish this?

Thanks in advance.

1

There are 1 best solutions below

2
H.A.H. On

This is more "comment" than an answer. Usually I would do something like:

builder.Services.AddSingleton(new HttpClient() { BaseAddress = new Uri("..."), Timeout...

In my MauiProgram.cs.

And then inject it in constructors of other services, more or less like that:

readonly HttpClient httpClient;
public MyService(HttpClient httpClient){
   this.httpClient = httpClient;
}

And it works.

But instead of injecting the HttpClient, you can add a Singleton service, with HttpClient inside it.

class MyHttpClientService : IMyHttpClientService 
{
    HttpClient httpClient;
    //Get method - use it in your other services constructors
    //Init - use it when you can (after your "load")
}

And you can inject your service, instead of the client directly:

readonly HttpClient httpClient;
public MyService(IMyHttpClientService myHttpClientService){
   this.httpClient = myHttpClientService.GetHttpClient();
}

I have to warn you, that some network changes may make your HttpClient no longer usable, and you will have to re-create it. This is the only downside I know. Besides the extra work to deal with it.

And here is why I go with all this:

I use MAUI for mobile development.

While you can run your .NET Web API on your linux server, and spam 100+ "new HttpClient()" each second, and get away with it, on mobile the situation is not the same.

HttpClient is, HttpMessageInvoker, and because it implements IDisposable, it can deceive you that you can make as many instances as you like, and dispose them without problems whenever you want.

However, in mobile you have different versions of android, on top of different versions of linux, on different hardware, with different drivers, etc, etc, etc...

On IOS you have less variables to worry about, but when you pull the line, the situation is not so much better.

The end result - when you dispose some resource, when and if the OS will get it back, is very difficult to predict. And when you start getting random runtime exception, because you are out of sockets, nothing can fix it anymore.

My information is from more than year ago, maybe someone have implemented a working http client factory for MAUI now. Just make sure it is tested on actual physical devices. Not emulators or windows machine.