PrismLibrary / Prism

Prism is a framework for building loosely coupled, maintainable, and testable XAML applications in WPF, Xamarin Forms, and Uno / Win UI Applications..
Other
6.33k stars 1.64k forks source link

[Bug] Unable to register HttpClient using Microsoft.Extensions.DependencyInjection #2422

Closed BChapoulie closed 3 years ago

BChapoulie commented 3 years ago

Description

I am using Prism in a WPF application. Updating the Prism Nuget from version 7 to version 8 raises a bug in my program.

I have the app class which can be defined as follow:

public partial class App : Prism.DryIoc.PrismApplication
{
    protected override void RegisterTypes(IContainerRegistry containerRegistry)
    {
        containerRegistry.RegisterServices(
            serviceCollection =>
            {
                serviceCollection.AddHttpClient("APIClient",
                    settings => 
                    {
                        settings.BaseAddress = new Uri();
                    });
            });
        containerRegistry.Register<IHttpService, HttpService>();
    }

    protected override IContainerExtension CreateContainerExtension()
    {
        var extension = new DryIocContainerExtension();
        ContainerLocator.SetContainerExtension(() => extension);
        return ContainerLocator.Current;
    }

    protected override Window CreateShell() => Container.Resolve<MainWindow>();
}

The MainWindow is a WPF window which just contains a ContentView. The latest is to be associated to a ContentViewModel which takes a IHttpService as a parameter of the constructor. The IHttpService is an interface defining some http operations. The HttpService is its implementation which takes an HttpClient as a constructor parameter.

public class HttpService : IHttpService
{
    HttpClient _client;

    public HttpService(HttpClient client) 
    {
        _client = client;
    }
}

Steps to Reproduce

  1. Create a simple WPF Application
  2. Create the app as set in the code before with the service provided
  3. Create a couple of View-ViewModel to be associated and ask the ViewModel to have a HttpService as constructor parameter

Or

  1. Open the solution in the attached source and run the project

Expected Behavior

The window to be instanciated and working fine.

Actual Behavior

System.Windows.Markup.XamlParseException: ''La propriété Set 'Prism.Mvvm.ViewModelLocator.AutoWireViewModel' raised an exception.' line number '14' and line position '56'.'

Inner exception 1

ContainerResolutionException: An unexpected error occurred while resolving 'Application.WPF.ViewModels.ContentViewModel'

Inner exception 2

ContainerException: code: Error.UnableToResolveUnknownService; message: Unable to resolve Microsoft.Extensions.DependencyInjection.IServiceScopeFactory as parameter "scopeFactory" (IsSingletonOrDependencyOfSingleton) in resolution root Singleton Microsoft.Extensions.Http.DefaultHttpClientFactory {DryIoc.IfUnresolved.ReturnDefaultIfNotRegistered} FactoryId=168 (IsSingletonOrDependencyOfSingleton, IsResolutionCall) from container without scope with Rules with {TrackingDisposableTransients, UseDynamicRegistrationsAsFallbackOnly, FuncAndLazyWithoutRegistration, SelectLastRegisteredFactory} and without {ThrowOnRegisteringDisposableTransient, UseFastExpressionCompilerIfPlatformSupported} with FactorySelector=SelectLastRegisteredFactory with Made={FactoryMethod=ConstructorWithResolvableArguments} Where no service registrations found and no dynamic registrations found in 1 of Rules.DynamicServiceProviders and nothing found in 0 of Rules.UnknownServiceResolvers

Basic Information

Reproduction Link

PrismResolveHttpService.zip

Potential solution

A potential solution I came up with was to register directly the HttpClient doing such:

containerRegistry.Register<HttpClient>(() => new HttpClient());
containerRegistry.Register<IHttpService, HttpService>();

Even though this works it doesn't use the AddHttpClient extension from Microsoft.Extensions.DependencyInjection which configures the HttpClient with a lot of settings which is quite convenient and I'd like to still be able to use that.

brianlagunas commented 3 years ago

Prism does not support Microsoft.Extensions.DependencyInjection. You are using a package that is not an official Prism package.

dansiegel commented 3 years ago

Prism.DryIoc and Prism.DryIoc.Extensions are not meant to be used side by side for one thing... for another you're reporting your issue to the wrong repo... and while the ContainerExtensions are specifically tested for compatibility with Microsoft's AddHttpClientFactory... but it appears that you're doing your own thing for which you are on your own unless you would like a paid support contract.