blog
blog copied to clipboard
Using Dependency Injection in .NET Core Console Apps
Written on 08.02.2017 11:17:49
URL: http://asp.net-hacker.rocks/2017/02/08/using-dependency-injection-in-dotnet-core-console-apps.html
Comment written by Rojan Gh. on 26.03.2018 23:41:32
Thanks for the post. Straight to the point.
I'm trying to use the approach in a console app, in which I also want to inject the Service Provider (IServiceProvider) itself to a singleton using the DI (I have done this in asp.net core before), however it seems not to be working and I get an error message which reads as: "Unable to resolve service for type 'Microsoft.Extensions.DependencyInjection.ServiceProvider' while attempting to activate 'Project.Startup'".
Can you please help figure what it might be?
PS: I'm using Microsoft.Extensions.DependencyInjection 2.0.0 with .Net Core 2.0 if that helps.
Comment written by Jürgen Gutsch on 27.03.2018 07:25:13
Hi Rojan,
Hmm.... I need to try it first by myself.
Maybe you also need to reference the Abstractations: https://www.nuget.org/packa...
But I'm not really sure yet, until I tried it by myself.
I will do it in the next days and come back to you.
Comment written by Rojan Gh. on 27.03.2018 10:12:20
Thanks for the reply Jürgen.
I'm trying to go through the source codes to find a clue right now.
Please keep me posted if you could figure out a solution.
Comment written by Rojan Gh. on 27.03.2018 21:37:07
OK, never mind. Turns out I was trying to inject "ServiceProvider" while I had to inject "IServiceProvider" instead.
Thanks anyway. :)
Comment written by Emilian on 16.06.2018 14:41:28
But how do you resolve service provider in other classes in your application? Is this a singleton?
Comment written by Jürgen Gutsch on 18.06.2018 08:06:10
The IServiceProvider should be available by default. IMO
Comment written by am on 25.09.2018 10:22:09
Hi Jürgen Gutsch,
How may i use DI in .NET Core class library project?
Comment written by Jürgen Gutsch on 01.10.2018 08:05:10
Hi @disqus_kotMQ7NydX:disqus
The DI container need to be initialized/set-up in an application project. Means in a project that can be run directly. Than it can be used in a class library to add services. Like this:
http://asp.net-hacker.rocks...
Hi, Question what if your using DI on web app, where you build your services in Startup.cs. Later you have some business class, from which you should access to some IRepository and do somethings ? If you initialize from constructor that is requesting to have also in some controller same initialization. How I can in controller just call class which is doing some business and that class is calling specific service ? Example:
public class INameRepository {
Task<string> Data();
}
public class NameRepository: INameRepository{
private readonly DbContext _context;
public NameRepository(DbContext context){
_context = context;
}
public async Task<string> Data(){
_context.Entity.LastOrDefaultAsync();
}
}
public class SomeBusiness{
// Here I need to use INameRepository
}
public class SomeController: ControllerBase
{
public async Task<IActionResult> Index(){
var business = new SomeBusiness();
return Ok();
}
}
in Startup.cs under it is added
public void ConfigureServices(IServiceCollection services)
{
services.AddScopped<INameRepository,NameRepository>();
}
Thanks in Advance, Danijel
Hello @danijel88
Many thanks for your comment.
You should request the business logic via DI as well. First inject the repository to the business logic via the constructor, create an interface for the business logic ad register it to the DI too. Than inject the business logic via the constructor into the controller.
public class INameRepository {
Task<Entity> Data();
}
public class NameRepository : INameRepository
{
private readonly AppDbContext _context;
public NameRepository(AppDbContext context)
{
_context = context;
}
public async Task<Entity> Data()
{
_context.Entities.LastOrDefaultAsync();
}
}
public class ISomeBusiness
{
Entity Data();
}
public class SomeBusiness
{
// Here I need to use INameRepository
private readonly INameRepository _repo;
public SomeController(INameRepository repo)
{
_repo = repo;
}
public async Entity Data()
{
return await _repo.Data()
}
}
public class SomeController : ControllerBase
{
private readonly ISomeBusines _busines;
public SomeController(ISomeBusines busines)
{
_busines = busines;
}
public async Task Index()
{
var data = await _busines.Data();
return Ok();
}
}
In the Startup.cs it should look like this:
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<AppDbContext>(options =>
options.UseSqlite(Configuration.GetConnectionString("DefaultConnection")));
services.AddScopped<INameRepository, NameRepository>();
services.AddScopped<ISomeBusiness, SomeBusiness>();
}
Hope that helps.
Cheers, Juergen