SoFunction
Updated on 2025-03-10

Core MVC controller requests dependency injection

Core MVC controllers should explicitly request their dependencies through constructors, and in some cases a single controller may require a service to operate, and requests at the controller level may not make sense. In this case, the service can also be used as a parameter to the Action.

Dependency injection is a technology as shown in Dependency Inversion Principle that allows applications to loosely couple module compositions.

1. Constructor Injection

Core's built-in constructor-based dependency injection support extends to MVC controllers. By adding only one service type as a constructor parameter to the controller, Core will attempt to parse this type using the built-in service container. Services are usually (but not always) defined using interfaces. For example, if the application defines a service that retrieves time, then depend on injection instead of hardcoded:

Define interfaces and implementations:

namespace 
{
    public interface IDateTime
    {
        DateTime Now { get; }
    }
    public class SystemDateTime: IDateTime
    {
        public DateTime Now
        {
            get { return ; }
        }
    }
}

Register a service to the container in ConfigureServices:

<IDateTime, SystemDateTime>();

Use in control:

public class DateTimeController : Controller
    {
        private IDateTime _dateTime;
        public DateTimeController(IDateTime dateTime)
        {
            _dateTime = dateTime;
        }
        // GET: DateTime
        public ActionResult Index()
        {
            var serverTime = _dateTime.Now;
            if ( < 12)
            {
                ViewData["Message"] = "Good Morning";
            }
            return View();
        }
}

Core's built-in dependency injection supports that the types used to request services can only have one constructor, and if more than one will report an exception. Replace default dependency injection with a third-party implementation, which can implement support for multiple constructors.

2. Inject using FromServices operation

Sometimes, there is no need to serve multiple operations in the controller. In this case, it makes sense to inject the service into the parameters of the operation method. Implementation through the [FromServices] tag parameters:

public ActionResult Index([FromServices] IDateTime _dateTime)
        {
            var serverTime = _dateTime.Now;
            if ( < 12)
            {
                ViewData["Message"] = "Good Morning";
            }
            return View();
        }

3. Access settings in the controller

A common mode when accessing application settings or configuration settings in the controller. This access should use the access mode described in Configuration. Normally, you should not use dependency injection from the controller to request settings directly, a better way is to request an IOptions<T> instance, T is the configuration type you need. For example:

Create an option class:

public class AppSettingOptions
    {
        public DefaultConnec ConnectionStrings { get; set; }
        public string AllowedHosts { get; set; }
    }

    public class DefaultConnec
    {
        public string DefaultConnection { get; set; }
    }

{
  "ConnectionStrings": {
    "DefaultConnection": "Data Source=.;Initial Catalog=Test;Integrated Security=True"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information"
    }
  },
  "AllowedHosts": "*"
}

To configure the application to use the option model, add configuration classes to the service container in ConfigureServices:

public Startup(IConfiguration configuration,IHostingEnvironment env)
        {
            //Configuration = configuration;
            var builder = new ConfigurationBuilder()
                .SetBasePath(())
                .AddJsonFile("",optional:true,reloadOnChange:true)
                //.AddJsonFile($"appsettings.{}.json",optional:true)
                ;

            //Configure environment variables            //();
            Configuration = ();
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            ();
            &lt;AppSettingOptions&gt;(Configuration);
            //Written through code            &lt;AppSettingOptions&gt;(options=&gt;
            {
                 = "test";
            });
        }

The example is to read settings from   , or you can add settings in the code.

Once you specify the configuration object of AppSettingOptions of type AppSettingOptions and add it to the service container, you can get it in the controller or operation method through the instance requesting IOptions<AppSettingOptions>:

public class HomeController : Controller
    {
        private readonly IOptions<AppSettingOptions> _options;
        public HomeController(IOptions<AppSettingOptions> options)
        {
            _options = options;
        }
}

Following options mode allows settings and configurations to be separated from each other and ensures that the controller follows a separation of concerns, as there is no need to know how to find the settings information. Since there is no static attachment or direct instantiation of the setup class in the controller class, it makes the controller easier to use unit testing.

This is all about this article about Core MVC controller request dependency injection. I hope it will be helpful to everyone's learning and I hope everyone will support me more.