Reputation: 11185
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
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
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