.Net Core Dependency Injection inject out of constructor

15,952

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.

Share:
15,952
Tornike Choladze
Author by

Tornike Choladze

Updated on June 26, 2022

Comments

  • Tornike Choladze
    Tornike Choladze almost 2 years

    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
        }
    }
    
    • Pankaj Kapare
      Pankaj Kapare almost 7 years
      So what's question here?
    • Tornike Choladze
      Tornike Choladze almost 7 years
      Ho can I do it ? How can I inject services out of constructor ?
    • Pankaj Kapare
      Pankaj Kapare almost 7 years
    • Tornike Choladze
      Tornike Choladze almost 7 years
      I know how DI works and how to register services, but it can be injected only in Constructors ... I need injection out of it.
    • Parth Mehta
      Parth Mehta almost 7 years
      I think middleware is fit into your requirement. docs.microsoft.com/en-us/aspnet/core/fundamentals/middleware‌​.
    • Tornike Choladze
      Tornike Choladze almost 7 years
      no not middleware it's about injection I need to inject services WITHOUT CONSTRUCTOR IN CONTROLLERS
    • hakany
      hakany almost 7 years
      What do you mean with 'injection out'? At least a code sample would be useful to understand what your try to achieve.
    • juunas
      juunas almost 7 years
      Actually, you can inject via controller action method parameters. Just add [FromServices] in front of it.
    • Tornike Choladze
      Tornike Choladze almost 7 years
      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
    • Lenny32
      Lenny32 almost 7 years
      @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<IObject>();" Unfortunatly I do not know if it is working from a constructor
    • Tornike Choladze
      Tornike Choladze almost 7 years
      @Lenny32 yep I got an answer but your answer is the same thx anyway. IServiceProvider is all what I was looking for ))
    • Torbjörn Hansson
      Torbjörn Hansson almost 7 years
      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 docs.microsoft.com/en-us/aspnet/core/mvc/controllers/…
    • JWP
      JWP almost 7 years
      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.
    • Tornike Choladze
      Tornike Choladze almost 7 years
      @JohnPeters check updated question I added answer I got
    • John Deer
      John Deer over 3 years
      Unfreeze a question, please
  • Tornike Choladze
    Tornike Choladze almost 7 years
    THANK YOU I NEEDED "2. Resolve services manually" IServiceProvider for resolving services