Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How ASP.NET Core MVC creates controllers and dependency injection

2025-03-29 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/01 Report--

This article mainly introduces the relevant knowledge of "how to create controller and dependency injection in ASP.NET Core MVC". The editor shows you the operation process through an actual case. The operation method is simple, fast and practical. I hope this article "how to create controller and dependency injection in ASP.NET Core MVC" can help you solve the problem.

Default IControllerActivator

In ASP.NET Core, when the MVC middleware receives the request, the controller and operation method to be executed are selected by routing. In order to actually perform the operation, the MVC middleware must create an instance of the selected controller.

The process of creating a controller depends on many different provider and factory classes, but is ultimately determined by an instance that implements the IControllerActivator interface. The implementation class only needs to implement two methods:

Public interface IControllerActivator {object Create (ControllerContext context); void Release (ControllerContext context, object controller);}

As you can see, the IControllerActivator.Create method passes the ControllerContext instance used to create the controller. How the controller is created depends on the specific implementation.

As we all know, ASP.NET Core uses DefaultControllerActivator, which creates controllers through TypeActivatorCache. TypeActivatorCache calls the constructor of the class and attempts to parse an instance of the parameters required by the constructor from the DI container.

It is important that DefaultControllerActivator does not attempt to resolve instances of the controller from the DI container, only the dependencies of the controller.

DefaultControllerActivator example

To demonstrate this behavior, I created a simple MVC application that includes a single service and a controller. The service instance has a name property, which is set by the constructor. By default, it uses "default" as the default.

Public class TestService {public TestService (string name = "default") {Name = name;} public string Name {get;}}

In the application, HomeController depends on TestService and returns the value of the Name property:

Public class HomeController: Controller {private readonly TestService _ testService; public HomeController (TestService testService) {_ testService = testService;} public string Index () {return "TestService.Name:" + _ testService.Name;}}

There is another piece of code in the Startup file. Here I register TestService in the DI container as a scope service, and set up MVC middleware and services:

Public class Startup {public void ConfigureServices (IServiceCollection services) {services.AddMvc (); services.AddScoped (); services.AddTransient (ctx = > new HomeController (new TestService ("Non-default value");} public void Configure (IApplicationBuilder app) {app.UseMvcWithDefaultRoute ();}}

You will notice that I have defined a factory method to create an instance of HomeController. Register the HomeController type in the DI container and pass the custom Name property in the TestService instance.

If you run the application, what results will you see?

You can see that the TestService.Name property uses the default value, indicating that the TestService instance is obtained directly from the DI container, directly ignoring the factory method for creating the HomeController.

It's easy to understand that when you create a controller through DefaultControllerActivator, it doesn't create a HomeController instance from the DI container, it just parses the dependencies of the constructor.

In most cases, using DefaultControllerActivator is a good choice, but sometimes you may want to create a controller directly through the DI container, such as you want to use a third-party container with features such as interceptors or decorators.

Fortunately, the MVC framework includes one such IControllerActivator implementation and provides a very convenient extension to enable it.

ServiceBasedControllerActivator

As you can see, DefaultControllerActivator uses TypeActivatorCache to create the controller, and MVC includes another implementation, called ServiceBasedControllerActivator, which fetches the controller directly from the DI container. Its implementation is very simple:

Public class ServiceBasedControllerActivator: IControllerActivator {public object Create (ControllerContext actionContext) {var controllerType = actionContext.ActionDescriptor.ControllerTypeInfo.AsType (); return actionContext.HttpContext.RequestServices.GetRequiredService (controllerType);} public virtual void Release (ControllerContext context, object controller) {}}

When you add a MVC service to your application, you can configure the DI-based activator using the AddControllersAsServices () extension method:

Public class Startup {public void ConfigureServices (IServiceCollection services) {services.AddMvc () .AddControllers AsServices (); services.AddScoped (); services.AddTransient (ctx = > new HomeController (new TestService ("Non-default value"));} public void Configure (IApplicationBuilder app) {app.UseMvcWithDefaultRoute ();}}

With the code above, clicking on the home page will create a controller through the DI container. Since we have registered a factory method to create HomeController, our custom TestService configuration will be retained, using the replaced Name attribute:

The AddControllersAsServices method does two things-it registers all controllers in your application with the DI container (if not already registered) and registers IControllerActivator as ServiceBasedControllerActivator:

Public static IMvcBuilder AddControllersAsServices (this IMvcBuilder builder) {var feature = new ControllerFeature (); builder.PartManager.PopulateFeature (feature); foreach (var controller in feature.Controllers.Select (c = > c.AsType () {builder.Services.TryAddTransient (controller, controller);} builder.Services.Replace (ServiceDescriptor.Transient ()); return builder;}

If you need to do something more complicated, you can implement your own IControllerActivator; at any time, but I can't see any reason why these two implementations don't meet your needs!

That's all for "how ASP.NET Core MVC creates controllers and dependency injection". Thank you for reading. If you want to know more about the industry, you can follow the industry information channel. The editor will update different knowledge points for you every day.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report