I am using Microsoft.Extensions.DependencyInjection in .Net Farmework 4.6.2 class libraries. How to access IServiceCollection and/or IServiceProvider from outside the source code where they are instantiated, Main(), for instance? I could create a static class exposing this property in a separate class library and referenced it but I am wondering if there is any other better way of achieving this objective. .Net Framework has ServiceLocator.Current.GetInstance. Is there any similar thing in Microsoft.Extensions.DependencyInjection? Any advice and insight is appreciated.
An instance of IServiceProvider itself can be obtained by calling a BuildServiceProvider method of an IServiceCollection. IServiceCollection is a parameter of ConfigureServices method in a Startup class. It seems to be magically called with an instance of IServiceCollection by the framework.
Yes, you can access the database!
Resolve dependencies using IServiceProvider Once the container has been created, the IServiceCollection instance is composed into an IServiceProvider instance. You can use this instance to resolve services. You can inject an instance of type IServiceProvider into any method of a class.
So, the services you add in the IServiceCollection type instance, it actually creates an instance of ServiceDescriptor and adds it to the list. IServiceProvider includes GetService method. The ServiceProvider class implements IServiceProvider interface which returns registered services with the container.
There are three ways to get an instance of IServiceProvider : We can get the services in Configure method using IApplicationBuilder's ApplicationServices property as shown below. Want to check how much you know ASP.NET Core?
To do that, you use one of three methods available from the IServiceCollection class: AddScoped, AddTransient and AddSingleton. The syntax for all three is identical so, assuming you have a class called ShippingCalculator that implements the IShipCalc interface, you'd use code like this to add the class to the collection:
ServiceCollectionContainerBuilderExtensions class includes BuildServiceProvider extension method which creates and returns an instance of ServiceProvider . There are three ways to get an instance of IServiceProvider : We can get the services in Configure method using IApplicationBuilder's ApplicationServices property as shown below.
Different from the IServiceProvider
, the IServiceCollection
can't be injected into a class constructor.
As many have already said, you should avoid using them directly. But if you really need to do so for the IServiceCollection
, you can create a "Provider", such as:
public interface IServiceCollectionProvider
{
IServiceCollection ServiceCollection { get; }
}
public sealed class ServiceCollectionProvider: IServiceCollectionProvider
{
public ServiceCollectionProvider(IServiceCollection serviceCollection)
{
ServiceCollection = serviceCollection;
}
public IServiceCollection ServiceCollection { get; }
}
Registering:
services.AddSingleton<IServiceCollectionProvider>(new ServiceCollectionProvider(services));
Using:
public class YourController : Controller
{
private readonly IServiceProvider _provider;
private readonly IServiceCollection _services;
public YourController (IServiceProvider provider, IServiceCollectionProvider serviceCollectionProvider)
{
_provider = provider;
_services = serviceCollectionProvider.ServiceCollection;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With