Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IServiceProvider in ASP.NET Core

I starting to learn changes in ASP.NET 5(vNext) and cannot find how to get IServiceProvider, for example in "Model"'s method

public class Entity 
{
     public void DoSomething()
     { 
           var dbContext = ServiceContainer.GetService<DataContext>(); //Where is ServiceContainer or something like that ?
     }
}

I know, we configuring services at startup, but where all service collection staying or IServiceProvider?

like image 290
Sam Avatar asked May 01 '15 16:05

Sam


People also ask

How do I get an instance of IServiceProvider in .NET Core?

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.

What is the difference between GetService and GetRequiredService?

The difference is that GetService<T>() returns null if it can't find the service. GetRequiredService<T>() throws an InvalidOperationException instead.

What is IServiceCollection in .NET Core?

AddScoped(IServiceCollection, Type, Type) Adds a scoped service of the type specified in serviceType with an implementation of the type specified in implementationType to the specified IServiceCollection.

What is dependency injection in ASP.NET Core?

ASP.NET Core supports the dependency injection (DI) software design pattern, which is a technique for achieving Inversion of Control (IoC) between classes and their dependencies. For more information specific to dependency injection within MVC controllers, see Dependency injection into controllers in ASP.NET Core.


2 Answers

You have to bring in Microsoft.Extensions.DependencyInjection namespace to gain access to the generic

GetService<T>();

extension method that should be used on

IServiceProvider 

Also note that you can directly inject services into controllers in ASP.NET 5. See below example.

public interface ISomeService
{
    string ServiceValue { get; set; }
}

public class ServiceImplementation : ISomeService
{
    public ServiceImplementation()
    {
        ServiceValue = "Injected from Startup";
    }

    public string ServiceValue { get; set; }
}

Startup.cs

public void ConfigureService(IServiceCollection services)
{
    ...
    services.AddSingleton<ISomeService, ServiceImplementation>();
}

HomeController

using Microsoft.Extensions.DependencyInjection;
...
public IServiceProvider Provider { get; set; }
public ISomeService InjectedService { get; set; }

public HomeController(IServiceProvider provider, ISomeService injectedService)
{
    Provider = provider;
    InjectedService = Provider.GetService<ISomeService>();
}

Either approach can be used to get access to the service. Additional service extensions for Startup.cs

AddInstance<IService>(new Service())

A single instance is given all the time. You are responsible for initial object creation.

AddSingleton<IService, Service>()

A single instance is created and it acts like a singleton.

AddTransient<IService, Service>()

A new instance is created every time it is injected.

AddScoped<IService, Service>()

A single instance is created inside of the current HTTP Request scope. It is equivalent to Singleton in the current scope context.

Updated 18 October 2018

See: aspnet GitHub - ServiceCollectionServiceExtensions.cs

like image 89
Jaime Still Avatar answered Oct 22 '22 02:10

Jaime Still


I don't think it is a good idea for an entity (or a model) to have access to any service.

Controllers, on the other hand, do have access to any registered service in their constructors, and you don't have to worry about it.

public class NotifyController : Controller
{
    private static IEmailSender emailSender = null;
    protected static ISessionService session = null;
    protected static IMyContext dbContext = null;
    protected static IHostingEnvironment hostingEnvironment = null;

    public NotifyController(
                IEmailSender mailSenderService,
                IMyContext context,
                IHostingEnvironment env,
                ISessionService sessionContext)
    {
        emailSender = mailSenderService;
        dbContext = context;
        hostingEnvironment = env;
        session = sessionContext;
    }
}
like image 4
Leonardo Herrera Avatar answered Oct 22 '22 01:10

Leonardo Herrera