Cannot resolve implemented object while using generic type in asp.net .core

走远了吗. 提交于 2019-12-20 06:30:04

问题


My problem is simple! How can I resolve manually this registered interface:

services.AddScoped<ICommandHandler<Command>, AddProductCommandHandler>();

This code not work and always return null:

My DiContainer is like this:

public class ProviderDiContainer : IDiContainer
{
    private readonly ServiceProvider _container;

    public ProviderDiContainer(ServiceProvider container)
    {
        _container = container;
    }

    public T Resolve<T>()
    {        
       return _container.GetService<T>();
    }
}

Which is registered such:

public void ConfigureServices(IServiceCollection services)
{            
    var diContainer = new ProviderDiContainer(services.BuildServiceProvider());
    services.AddSingleton<IDiContainer>(c => diContainer);
//  Register some other things here      Registrar.RegisterSomethings(services);
    services.AddSingleton(s => new ServiceLocator(diContainer));
}

And my Service Locator is:

public class ServiceLocator
{
    public ServiceLocator(IDiContainer container)
    {
            Current = container;
    }

    public static IDiContainer Current
    {
        get;
        private set;
    }
}

Now when I call this code it returns null to me:

var commandHandler = ServiceLocator.Current.Resolve<ICommandHandler<TCommand>>();

Note: To resolve ServiceLocator and DbiContainer at first, I put them in Configure method of the StartUp


回答1:


Short answer: that' because you're building an another ServiceProvider which is different from the default one . Note the following code :

var diContainer = new ProviderDiContainer(services.BuildServiceProvider()); .

That means the you'll use the services collection to build a new ServiceProvider, and then pass that ServiceProvider to ProviderDiContainer. As a result, any services registered below that line will not be resolved by the ProviderDiContainer.

How to fix

  1. Instead of asking for a specific implementation, we should depends on abstraction (interface):
    public class ProviderDiContainer: IDiContainer {

        private readonly ServiceProvider _container; 
        private readonly IServiceProvider _container;

        public ProviderDiContainer(ServiceProvider container) 
        public ProviderDiContainer(IServiceProvider container)
        {
            _container = container;
        }

        public T Resolve<T>()
        {        
            return _container.GetService<T>();
        }
    }
  1. Don't build unnecessary ServiceProvider:
    var diContainer = new ProviderDiContainer(services.BuildServiceProvider());
    services.AddSingleton<IDiContainer>(c => diContainer);
     ... 
    services.AddSingleton(s => new ServiceLocator(diContainer));
    services.AddSingleton<IDiContainer>(sp => new ProviderDiContainer(sp));
    services.AddSingleton<ServiceLocator>();


来源:https://stackoverflow.com/questions/53922206/cannot-resolve-implemented-object-while-using-generic-type-in-asp-net-core

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!