26

Do you know how to manually resolve dependencies in .net core? Something like

DependencyResolver.Resolve<ISomeService>()

UPDATE I'm in a class that was not injected, I want to resolve it from the inside, rather than pass variables all over the place

3
  • stackoverflow.com/a/32461714/3606250 Commented Mar 3, 2019 at 20:05
  • Does this answer your question? Resolving instances with ASP.NET Core DI from within ConfigureServices Commented Jul 15, 2020 at 7:32
  • 2
    Just be aware that you're creating a maintenance nightmare, as you can no longer trust the dependencies injected via the constructor to be all the dependencies. It will invariably lead to test harnesses that have to set up every service for every test, just because you lost control over which services are needed. Commented Jul 15, 2020 at 7:42

2 Answers 2

12

Add your dependency in ConfigureServices as below

public void ConfigureServices(IServiceCollection services){
    //AddSingleton or AddTransient based on your requirements
    services.AddTransient<ISomeService, ConcreteService>();
}

In your controller or anywhere, add IServiceProvider in the constructor like below:

using Microsoft.Extensions.DependencyInjection;

...

public class HomeController
{
  ...
  public HomeController(IServiceProvider serviceProvider)
  {
      var service = serviceProvider.GetService<ISomeService>();
  }
}

@Shazam, Here are some notes or suggestions based on your comment:

  • If you can not inject because you might not have a constructor in this class, I woud suggest to add a paramter to your function and pass the resolved dependency from outside

  • Another Idea is to add a static property and initialize its value in ConfigureServices

For Example:

public static class MyClass
{
    public static ISomeService MyServiceObj { set; get; }
    ....
}

In your ConfigureServices

   public void ConfigureServices(IServiceCollection services){
        services.AddTransient<ISomeService, ConcreteService>();
        MyClass.MyServiceObj = services.GetService<ISomeService>();
    }

Hope this helps, please rate my answer or leave me a comment if you still in doubt how to do it

Sign up to request clarification or add additional context in comments.

7 Comments

At design time you should know which dependencies your controller would have, inject IServiceProvider seems a bad idea, I'd inject only the service I know I will need...
@Juan I did it in this way based on his question giving him the choice to manually inject what he needs but it seems he doesn't have constructor in his class, thanks though for your note
@Shazam If you can not inject I woud suggest to add a paramter to your function and pass the resolved dependency from outside
Another Idea is to add a static method and initialize its value after resolve in ConfigureServices
@msoliman can you please add more details on the last comments? Thanks
|
1

If you're trying to get scoped objects in a singleton object (like a BackgroundService), then serviceProvider.GetService method will raise an error stating this. The solution is getting IServiceProvider during construction then when needed (in this case ExecuteAsync) a new scope should be created and all needed objects should be created in this scope.

public class MyService:BackgroundService 
{
  private readonly IServiceProvider _serviceProvider;
  public MyService(IServiceProvider serviceProvider)
  {
    _serviceProvider = serviceProvider;
  }

  protected override Task ExecuteAsync(CancellationToken stoppingToken)
  {
    using (var scope = _serviceProvider.CreateScope())
    {
      var services = scope.ServiceProvider;            
      var logger = services.GetRequiredService<ILogger<MyService>>();
      logger?.LogInformation("MyService: ExecuteAsync");
      return Task.CompletedTask;
    }
  }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.