ASP. NET Core MVC dependency injection View and Controller

  • 2021-12-04 18:27:51
  • OfStack

Directory 1. Dependency injection for ASP. NET Core MVC View 1. Populate lookup data 2. Override service 2. Dependency injection for ASP. NET Core MVC Controller 1. Constructor injection 2. Use FromServices operation injection 3. Access settings in controller

1. ASP. NET Core MVC dependency injection View

   ASP.NET Core Supports the use of dependency injection in attempts. This will help provide view-specific services, such as localization or data that is only used to populate the elements of the view. Try to keep the separation of concerns between the controller and the view. Most of the data displayed by the view should be passed in from the controller.

Use @inject Directive injects services into the view, syntax @inject <type> <name>  ,

For example:


@model MVCTest.Models.Operation
@using MVCTest.Services
@inject BaseInfoServices BaseInfoServices

@{
    ViewData["Title"] = "Create";
}
<ul>
    @foreach (var city in BaseInfoServices.GetCities())
    {
    <li>@city</li>
    }
</ul>

    public class BaseInfoServices
    {
        public List<string> GetCities()
        {
            return new List<string>();
        }
    }

Need to be in advance in ConfigureServices Add the service to the container.

1. Populate the lookup data

View injection helps populate UI elements, such as drop-down box lists. For example, a form including gender, state and other user information. If you render this form in the standard MVC way, you need the controller to request a data access service for each set of options, and then populate each set of bound options into the model or ViewBag Medium.

The other is to inject services directly into the view to obtain these option data. This approach minimizes the amount of controller code and moves the logic to construct the elements of the view to the view itself. Controller Action Just send the user data to a form.

2. Rewrite the service

In addition to injecting services, this technique can also be used to rewrite previously injected services on pages. For example, replace the default HTML Helper :


@model MVCTest.Models.Operation
@using MVCTest.Services
@inject BaseInfoServices BaseInfoServices
@inject MyHtmlHelper Html


Use in a view @Html The custom service will be invoked.

If you want to extend an existing service rather than replace it, you simply use this technique and let the service inherit or encapsulate the existing implementation.

2. ASP. NET Core MVC dependency injection Controller

ASP.NET Core MVC Controllers should explicitly request their dependencies through constructors. In some cases, the operation of a single controller may require 1 service, and requests at the controller level may be meaningless. In this case, you can also take the service as a parameter of Action.

Dependency injection is a kind of Dependency Inversion Principle The technology shown allows the application to be loosely coupled by module composition.

1. Constructor injection

  @inject0 Built-in constructor-based dependency injection support extends to MVC controllers. By adding only one service type as a constructor parameter to the controller, ASP.NET Core An attempt will be made to resolve this type using the built-in service container. Services usually (but not always) use interface definitions. For example, if your application defines a service that retrieves time and then relies on injection instead of hard coding:

Define interfaces and implementations:


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

In ConfigureServices Register services to containers in:


services.AddTransient<IDateTime, SystemDateTime>();


To 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 (serverTime.Hour < 12)
            {
                ViewData["Message"] = "Good Morning";
            }
            return View();
        }
}

   ASP.NET Core Built-in dependency injection support for requesting a service type can have only one constructor, and an exception will be reported if more than one. Supporting multiple constructors can be implemented by replacing default dependency injection with a third-party implementation.

2. Inject using FromServices operation

Sometimes, there is no need to provide services for multiple operations in the controller. In this case, it makes sense to inject services into the parameters of the operation method. Pass [FromServices] Mark parameters to implement:


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

3. Access settings in the controller

Common mode when accessing application settings or configuring settings in the controller. This access should be used in the Configuration The access mode described in. It is generally not appropriate to request settings directly from the controller using dependency injection. A better way is to request 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; }
    }

appsettings. json:


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

Configure the application to use the option model, in the ConfigureServices Add configuration classes to the service container:


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

            // Configure environment variables 
            //builder.AddEnvironmentVariables();
            Configuration = builder.Build();
        }

        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)
        {
            services.AddOptions();
            services.Configure<AppSettingOptions>(Configuration);
            // Written by code 
            services.Configure<AppSettingOptions>(options=>
            {
                options.AllowedHosts = "test";
            });
        }

The example is from the appsettings.json Read settings, or add settings in your code.

1 denier specifies the configuration object of the please type AppSettingOptions And add it to the service container, you can request IO in the controller or operation method by requesting IO @inject <type> <name> 0 Gets it from an instance of:


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

The Follow Options pattern allows settings and configurations to be separated from each other and ensures that the controller follows the separation of concerns because there is no need to know how and where to find the settings information. Because there is no static attachment or direct instantiation of the settings class in the controller class, unit testing is easier for the controller to use.


Related articles: