问题
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
- 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>(); } }
- 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