SexyMF
SexyMF

Reputation: 11185

.net core resolve dependency manually anywhere in the code

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

Upvotes: 25

Views: 22797

Answers (2)

uuctum
uuctum

Reputation: 23

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;
    }
  }
}

Upvotes: 1

Muhammad Soliman
Muhammad Soliman

Reputation: 23876

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

Upvotes: 12

Related Questions