blog icon indicating copy to clipboard operation
blog copied to clipboard

Using Dependency Injection in .NET Core Console Apps

Open JuergenGutsch opened this issue 6 years ago • 10 comments

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

JuergenGutsch avatar Nov 16 '18 21:11 JuergenGutsch

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.

JuergenGutsch avatar Nov 16 '18 21:11 JuergenGutsch

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.

JuergenGutsch avatar Nov 16 '18 21:11 JuergenGutsch

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.

JuergenGutsch avatar Nov 16 '18 21:11 JuergenGutsch

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. :)

JuergenGutsch avatar Nov 16 '18 21:11 JuergenGutsch

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?

JuergenGutsch avatar Nov 16 '18 21:11 JuergenGutsch

Comment written by Jürgen Gutsch on 18.06.2018 08:06:10

The IServiceProvider should be available by default. IMO

JuergenGutsch avatar Nov 16 '18 21:11 JuergenGutsch

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?

JuergenGutsch avatar Nov 16 '18 21:11 JuergenGutsch

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...

JuergenGutsch avatar Nov 16 '18 21:11 JuergenGutsch

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

danijel88 avatar Jan 10 '19 12:01 danijel88

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

JuergenGutsch avatar Jan 10 '19 21:01 JuergenGutsch