0

In Startup:

services.AddTransient<IMyService, MyService>()

Controller method:

[HttpGet]
public JsonResult GetSomething()
{
    Helper helper = new Helper(new MyService()); // works but looking better solution
    return Ok("");
}

Helper class:

public class Helper
{
    private readonly IMyService myService;

    public Helper(IMyService myService)
    {
        this.myService = myService;
    }

    public Helper()
    {
         this.myService = ?;
    }
}

I want to instantiate Helper class without inject the dependency manually with new MyService(). The MyService() class should be the class in startup. I also want to place the the Helper class in another assembly.

I see some code with

var service = (IFooService)serviceProvider.GetService(typeof(IMyService));

but i don't know how to get a serviceProvider instance without injecting it to the helper.

Xeddon
  • 429
  • 8
  • 18
  • Does this answer your question? [Resolving instances with ASP.NET Core DI](https://stackoverflow.com/questions/32459670/resolving-instances-with-asp-net-core-di) – Yauheni Pakala Dec 07 '19 at 23:07
  • https://medium.com/@chrisverwijs/a-step-by-step-guide-to-using-ninject-for-dependency-injection-in-c-68a125bd7fa4 – Joel Wiklund Dec 07 '19 at 23:17
  • Then register helper and inject that to the controller. The container will inject relevant dependencies. – Nkosi Dec 07 '19 at 23:32

2 Answers2

3

Add the helper to the container

services.AddTransient<IMyService, MyService>()
services.AddScoped<Helper>(sp => new Helper(sp.GetRequiredService<IMyService>()));

And explicitly inject it into the controller

public class MyController: Controller {
    private readonly Helper helper;

    public MyController(Helper helper) {
        this.helper = helper;
    }    

    [HttpGet]
    public JsonResult GetSomething() {
        //...use helper 

        return Ok("");
    }

    //...
}

Ideally the helper should be derived from an abstraction as well

public class Helper : IHelper {
    private readonly IMyService myService;

    public Helper(IMyService myService) {
        this.myService = myService;
    }

    //...
}

And added accordingly to the container

services.AddTransient<IMyService, MyService>()
services.AddScoped<IHelper, Helper>();

to avoid the controller having tight coupling to concretions (implementation concerns).

public class MyController: Controller {
    private readonly IHelper helper;

    public MyController(IHelper helper) {
        this.helper = helper;
    }    

    [HttpGet]
    public JsonResult GetSomething() {
        //...use helper 

        return Ok("");
    }

    //...
}
Nkosi
  • 235,767
  • 35
  • 427
  • 472
  • `services.AddScoped(sp => new Helper(sp.GetRequiredService()));` could just be `services.AddScoped();`. No need to manually grab the dependency. – Chris Pratt Dec 09 '19 at 14:26
2

A way to properly resolve the service via DI:

[HttpGet]
public JsonResult GetSomething([FromServices] IMyService myService)
{
    Helper helper = new Helper(myService);
    return Ok("");
}

Or you inject it via ctor and use it in the method.

Rico Suter
  • 11,548
  • 6
  • 67
  • 93