11

I need to inject out of constructor, everything I declared in Setup.

Ho can I do it ? How can I inject services out of constructor ? Something like Injector service in Angular 2.

INJECT SERVICES WITHOUT CONSTRUCTOR IN CONTROLLERS

something like this

    public class ControllerBase : Controller
    {
        protected IRepository<Test> _test;
        protected IRepository<Test1> _test1;
        protected IRepository<Test2> _test2;

        public ControllerBase(INJECTOR injector)
        {
            _test = injector.inject(IRepository<Test>);
            _test1 = injector.inject(IRepository<Test1>);
            _test2 = injector.inject(IRepository<Test2>);
        }
    }

    public class SomeController : ControllerBase
    {
        public SomeController(INJECTOR injector)
            : base(injector)
        {

        }
    }

THANKS FOR ANSWER @Rick van den Bosch

FOR THOSE WHO STILL CAN'T GET WHAT I WANTED:

public class ControllerBase : Controller
{
    protected IRepository<Test> _test;
    protected IRepository<Test1> _test1;
    protected IRepository<Test2> _test2;

    public ControllerBase(IServiceProvider injector)
    {
        _test = injector.GetService<IRepository<Test>>();
        _test1 = injector.GetService<IRepository<Test1>>();
        _test2 = injector.GetService<IRepository<Test2>>();
    }
}

public class SomeController : ControllerBase
{
    public SomeController(IServiceProvider injector)
        : base(injector)
    {
        //HERE I HAVE ALL 3 REPO NOW WITHOUT EXTRA LINES
    }
}
public class SomeController1 : ControllerBase
{
    public SomeController1(IServiceProvider injector)
        : base(injector)
    {
        //HERE I HAVE ALL 3 REPO NOW WITHOUT EXTRA LINES
    }
}
Tornike Choladze
  • 274
  • 1
  • 3
  • 11
  • So what's question here? – Pankaj Kapare Jun 13 '17 at 11:14
  • 1
    Ho can I do it ? How can I inject services out of constructor ? – Tornike Choladze Jun 13 '17 at 11:15
  • Have look at this https://learn.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection – Pankaj Kapare Jun 13 '17 at 11:19
  • 1
    I know how DI works and how to register services, but it can be injected only in Constructors ... I need injection out of it. – Tornike Choladze Jun 13 '17 at 11:28
  • I think middleware is fit into your requirement. https://learn.microsoft.com/en-us/aspnet/core/fundamentals/middleware. – Parth Mehta Jun 13 '17 at 11:36
  • 1
    no not middleware it's about injection I need to inject services WITHOUT CONSTRUCTOR IN CONTROLLERS – Tornike Choladze Jun 13 '17 at 11:40
  • What do you mean with 'injection out'? At least a code sample would be useful to understand what your try to achieve. – hakany Jun 13 '17 at 11:41
  • 1
    Actually, you can inject via controller action method parameters. Just add `[FromServices]` in front of it. – juunas Jun 13 '17 at 11:41
  • 1
    thx juunas actually I need something like that but as variable, I am writing base controller and I want to inject default services without declaring them in constructor – Tornike Choladze Jun 13 '17 at 11:48
  • @ITTeam Is that what you are looking for? Here is the way to get the service provider from a controller without dependency injection. "return this.HttpContext.RequestServices.GetService();" Unfortunatly I do not know if it is working from a constructor – Lenny32 Jun 13 '17 at 12:00
  • @Lenny32 yep I got an answer but your answer is the same thx anyway. IServiceProvider is all what I was looking for )) – Tornike Choladze Jun 13 '17 at 12:06
  • Your example seem to use a service locator. You probably want to use ctor injection. Here's a link where you can read a bit about dependency injection and inversion of control in asp.net core https://learn.microsoft.com/en-us/aspnet/core/mvc/controllers/dependency-injection – Torbjörn Hansson Jun 13 '17 at 12:45
  • Actuall the pattern you show is not favoring composition over inheritance. The code is saying "My controllers are repositories for test" when in fact they should only direct traffic to the true repositories for test. Create models and use strong type binding instead. Call the method in the model/viewmodel that does what you want from the controller. Don't implement the DAL in the controller. – JWP Jun 13 '17 at 13:16
  • 1
    @JohnPeters check updated question I added answer I got – Tornike Choladze Jun 13 '17 at 13:49
  • Unfreeze a question, please – John Deer Sep 23 '20 at 10:25

1 Answers1

6

You can inject the service as a parameter to the action method. This is done by marking the parameter with the attribute [FromServices].

This looks something like this:

public IActionResult About([FromServices] IDateProvider dateProvider)
{
    ViewData["Message"] = $"Current date is {dateProvider.CurrentDate}";

    return View();
}

If you're looking for default services in a BaseController: you could go about that several ways:

1. Still use a constructor
This would look something like this:

public class HomeController : BaseController
{
    public HomeController(IDateProvider dateProvider) : base(dateProvider)
    {
    }
}

and

public class BaseController
{
    protected IDateProvider _dateProvider;

    protected BaseController(IDateProvider dateProvider)
    {
        _dateProvider = dateProvider;
    }
}

This way the IDateProvider is available to both the BaseController and all inheriting Controllers.

2. Resolve services manually
This way you resolve the service manually. This could be in the BaseController, and only when you need them (lazy). For more info, see this post.

For simplicity and readability I would probably choose the constructor one.

rickvdbosch
  • 14,105
  • 2
  • 40
  • 53