Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Register IHttpClientFactory inside UnityContainer #53273

Closed
Kingdom-Of-Heaven opened this issue May 25, 2021 · 9 comments
Closed

Register IHttpClientFactory inside UnityContainer #53273

Kingdom-Of-Heaven opened this issue May 25, 2021 · 9 comments

Comments

@Kingdom-Of-Heaven
Copy link

I am trying to register IHttpClientFactory. Firslty I've implemented it into my service:

public class WebApiService : IWebApiService
{
   private readonly IHttpClientFactory _httpClientFactory;
   public WebApiService(IHttpClientFactory httpClientFactory) => _httpClientFactory = httpClientFactory;
}

Nevertheless i am not sure how should i correctly register it in DI UnityContainer. Can anyone help me out?

namespace MobileAppXamarinForms
{
    public partial class App : Application
    {
        var container = new UnityContainer()
                .AddExtension(new Diagnostic())
                .RegisterInstance(mapper)
                .RegisterType<IDb, Db>(new ContainerControlledLifetimeManager())
                .RegisterType<IPageService, PageService>(new ContainerControlledLifetimeManager())
    }
    ...

}

So far i've tried to add ServiceCollection and register it and i hoped i will help to resolve IHttpClientFactory but it doesn't work and i get error as folows:

namespace MobileAppXamarinForms
{
   public partial class App : Application
   {

        IServiceCollection serviceCollection = new ServiceCollection();
        serviceCollection.AddHttpClient();
        serviceCollection.BuildServiceProvider();


        var container = new UnityContainer()
                    .AddExtension(new Diagnostic())
                    .RegisterInstance(mapper)
                    .RegisterInstance(serviceCollection)    // <======
                    .RegisterType<IDb, Db>(new ContainerControlledLifetimeManager())
                    .RegisterType<IPageService, PageService>(new ContainerControlledLifetimeManager())
    }
    ...
    
}

When debugging error shows:

Unity.ResolutionFailedException: 'The current type, System.Net.Http.IHttpClientFactory, is an interface and cannot be constructed. Are you missing a type mapping?

@javiercn javiercn transferred this issue from dotnet/aspnetcore May 26, 2021
@dotnet-issue-labeler
Copy link

I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.

@dotnet-issue-labeler dotnet-issue-labeler bot added the untriaged New issue has not been triaged by the area owner label May 26, 2021
@KevinCathcart
Copy link
Contributor

Registering the service collection is not going to be useful. The service collection is just a a list of registrations that need to be translated to the containers native format. To do that you can use the Unity.Microsoft.DependencyInjection NuGet package (written and maintained by the Unity team), which provides the needed code. While most examples show it as part of either using in asp.net core, or as part of using the Microsoft.Extensions.Hosting model, it can be used directly with the container.

To use, add a using directive with the Unity.Microsoft.DependencyInjection namespace. Then on your UnityContainer there should be a BuildServiceProvider extension method that takes an IServiceCollection, where you can pass your serviceCollection to register any entries inside it. This does not return support fluent chaining, so you want to have your UnityContainer in a variable when you call this. Alternatively you could cast the return value to Unity.Microsoft.DependencyInjection.ServiceProvider and then cast again to UnityContainer, in order to get back to the container, but that would be silly.

@ENikS This is another example where having the chainable AddServices method be public (unitycontainer/microsoft-dependency-injection#54) would probably be simpler for the user, since they are really only interested in being able to use a provided ServiceCollection extension method instead of needing to basically copy that code and manually convert to native registrations, and then need to monitor for any changes that might make in the future (this would be especially bad since some types registered are internal to Microsoft.Extensions.Http making registering them from user code tricky and fragile, but duplicating those types would be obnoxious, and an even larger maintenance burden on the user).

@Kingdom-Of-Heaven
Copy link
Author

@KevinCathcart Could you be so kind and show me how to do it in presented code of mine. I would appreciate.

@ghost
Copy link

ghost commented May 26, 2021

Tagging subscribers to this area: @dotnet/ncl
See info in area-owners.md if you want to be subscribed.

Issue Details

I am trying to register IHttpClientFactory. Firslty I've implemented it into my service:

public class WebApiService : IWebApiService
{
   private readonly IHttpClientFactory _httpClientFactory;
   public WebApiService(IHttpClientFactory httpClientFactory) => _httpClientFactory = httpClientFactory;
}

Nevertheless i am not sure how should i correctly register it in DI UnityContainer. Can anyone help me out?

namespace MobileAppXamarinForms
{
    public partial class App : Application
    {
        var container = new UnityContainer()
                .AddExtension(new Diagnostic())
                .RegisterInstance(mapper)
                .RegisterType<IDb, Db>(new ContainerControlledLifetimeManager())
                .RegisterType<IPageService, PageService>(new ContainerControlledLifetimeManager())
    }
    ...

}

So far i've tried to add ServiceCollection and register it and i hoped i will help to resolve IHttpClientFactory but it doesn't work and i get error as folows:

namespace MobileAppXamarinForms
{
   public partial class App : Application
   {

        IServiceCollection serviceCollection = new ServiceCollection();
        serviceCollection.AddHttpClient();
        serviceCollection.BuildServiceProvider();


        var container = new UnityContainer()
                    .AddExtension(new Diagnostic())
                    .RegisterInstance(mapper)
                    .RegisterInstance(serviceCollection)    // <======
                    .RegisterType<IDb, Db>(new ContainerControlledLifetimeManager())
                    .RegisterType<IPageService, PageService>(new ContainerControlledLifetimeManager())
    }
    ...
    
}

When debugging error shows:

Unity.ResolutionFailedException: 'The current type, System.Net.Http.IHttpClientFactory, is an interface and cannot be constructed. Are you missing a type mapping?

Author: Robert969696
Assignees: -
Labels:

area-System.Net, untriaged

Milestone: -

@KevinCathcart
Copy link
Contributor

@Robert969696 :

  1. Add the NuGet package. Many ways to do this. such as Visual Studio's Manage NuGet Packages, or from the command line you could do: dotnet add package Unity.Microsoft.DependencyInjection.
  2. Add using Unity.Microsoft.DependencyInjection to the top of the App file.
  3. Update code to be:
IServiceCollection serviceCollection = new ServiceCollection();
serviceCollection.AddHttpClient();

var container = new UnityContainer()
            .AddExtension(new Diagnostic())
            .RegisterInstance(mapper);
            
container.BuildServiceProvider(serviceCollection); 

 container.RegisterType<IDb, Db>(new ContainerControlledLifetimeManager())
            .RegisterType<IPageService, PageService>(new ContainerControlledLifetimeManager());
...

You can do the RegisterType calls before the the service collection, as part of the previous chain of methods, but I kept the registration order the same as you were trying to do in your original code for the sake of clarity.

I ran a simplified test version of this and this seemed to work fine for me.

@ghost
Copy link

ghost commented May 26, 2021

Tagging subscribers to this area: @dotnet/ncl
See info in area-owners.md if you want to be subscribed.

Issue Details

I am trying to register IHttpClientFactory. Firslty I've implemented it into my service:

public class WebApiService : IWebApiService
{
   private readonly IHttpClientFactory _httpClientFactory;
   public WebApiService(IHttpClientFactory httpClientFactory) => _httpClientFactory = httpClientFactory;
}

Nevertheless i am not sure how should i correctly register it in DI UnityContainer. Can anyone help me out?

namespace MobileAppXamarinForms
{
    public partial class App : Application
    {
        var container = new UnityContainer()
                .AddExtension(new Diagnostic())
                .RegisterInstance(mapper)
                .RegisterType<IDb, Db>(new ContainerControlledLifetimeManager())
                .RegisterType<IPageService, PageService>(new ContainerControlledLifetimeManager())
    }
    ...

}

So far i've tried to add ServiceCollection and register it and i hoped i will help to resolve IHttpClientFactory but it doesn't work and i get error as folows:

namespace MobileAppXamarinForms
{
   public partial class App : Application
   {

        IServiceCollection serviceCollection = new ServiceCollection();
        serviceCollection.AddHttpClient();
        serviceCollection.BuildServiceProvider();


        var container = new UnityContainer()
                    .AddExtension(new Diagnostic())
                    .RegisterInstance(mapper)
                    .RegisterInstance(serviceCollection)    // <======
                    .RegisterType<IDb, Db>(new ContainerControlledLifetimeManager())
                    .RegisterType<IPageService, PageService>(new ContainerControlledLifetimeManager())
    }
    ...
    
}

When debugging error shows:

Unity.ResolutionFailedException: 'The current type, System.Net.Http.IHttpClientFactory, is an interface and cannot be constructed. Are you missing a type mapping?

Author: Robert969696
Assignees: -
Labels:

area-Extensions-HttpClientFactory, untriaged

Milestone: -

@Kingdom-Of-Heaven
Copy link
Author

@KevinCathcart thanks, now it works !

@CarnaViire
Copy link
Member

Closing as answered above

@ENikS
Copy link
Contributor

ENikS commented May 29, 2021

This should be fixed in v6 of Unity
unitycontainer/microsoft-dependency-injection#54

@ghost ghost locked as resolved and limited conversation to collaborators Jun 28, 2021
@karelz karelz added this to the 6.0.0 milestone Jul 15, 2021
@karelz karelz removed the untriaged New issue has not been triaged by the area owner label Oct 20, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

6 participants