FromServices back

FromServices back

Due

 

These two days, I suddenly miss the era before 5 Asp.NET MVC, because there are so many projects I see a piece of code (in fact, more than a period, almost every Controller is)

 

    [Route("home")]
    [ApiController]
    public class HomeController : ControllerBase { private readonly IConfiguration configuration; private readonly IHostingEnvironment environment; private readonly CarService carService; private readonly PostServices postServices; private readonly TokenService tokenService; private readonly TopicService topicService; private readonly UserService userService; public HomeController(IConfiguration configuration, IHostingEnvironment environment, CarService carService, PostServices postServices, TokenService tokenService, TopicService topicService, UserService userService) { this.configuration = configuration; this.environment = environment; this.carService = carService; this.postServices = postServices; this.tokenService = tokenService; this.topicService = topicService; this.userService = userService; } [HttpGet("index")] public ActionResult<string> Index() { return "Hello world!"; } }

 

In the example of the constructor function declared dependency injection pile, have declared outside the respective received field cloned using code scanning, fragmented filled in each Controller's constructor. Before Asp.NET MVC 5, we can simplify the above code of the following form:

 

    [Route("home")]
    [ApiController]
    public class HomeController : ControllerBase { [FromServices] public IConfiguration Configuration { get; set; } [FromServices] public IHostingEnvironment Environment { get; set; } [FromServices] public CarService CarService { get; set; } [FromServices] public PostServices PostServices { get; set; } [FromServices] public TokenService TokenService { get; set; } [FromServices] public TopicService TopicService { get; set; } [FromServices] public UserService UserService { get; set; } public HomeController() { } [HttpGet("index")] public ActionResult<string> Index() { return "Hello world!"; } }

 

However, in .NETCore, the above code will complain it off, because that is characteristic: FromServicesAttribute can only be applied AttributeTargets.Parameter, navigate to FromServicesAttribute View source

 

namespace Microsoft.AspNetCore.Mvc
{
    /// <summary>
    /// Specifies that an action parameter should be bound using the request services.
    /// </summary>
    /// <example> /// In this example an implementation of IProductModelRequestService is registered as a service. /// Then in the GetProduct action, the parameter is bound to an instance of IProductModelRequestService /// which is resolved from the request services. /// /// <code> /// [HttpGet] /// public ProductModel GetProduct([FromServices] IProductModelRequestService productModelRequest) /// { /// return productModelRequest.Value; /// } /// </code> /// </example> [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = true)] public class FromServicesAttribute : Attribute, IBindingSourceMetadata { /// <inheritdoc /> public BindingSource BindingSource => BindingSource.Services; } }

 

So the question is, AttributeUsage is when removed AttributeTargets.Property it? The answer is: November 17, 2015, is called  Pranav K  buddy leather the FromServiceAttribute life, here is his code commit record

 

Limit [FromServices] to apply only to parameters
https://github.com/aspnet/Mvc/commit/2a89caed05a1bc9f06d32e15d984cd21598ab6fb

 

This man Commit Message is very simple: limit FromServices only act on the parameters. Master contest of strength, ruthless people did not talk much, fatal knife! Since then, the majority of developers to bid farewell to the property .NETCore injection. After I searched unremitting efforts, in fact, found in the code after Pranav K filed two days later, he actually he opened a Issue, you say people do not gas?

 

FromServices discussion on the abolition of
https://github.com/aspnet/Mvc/issues/3578

 

In this post there, many developers expressed their dissatisfaction, I saw someone like me, they want to express a simple constructor of this simple request; however, for property implantation may lead to problems of abuse also had a heated discussion, as well as property injection requirement must be marked as public members of these mandatory requirements, have to say, this post successfully attracted people's attention, but it is clear that the author does not intend to modify the properties FromServices support injection.

 

living comfortably without anybody's help

 

It does not matter, there is no official word comes, we make one yourself is the same effect, before that, we should also focus on another way to obtain an instance of the service in the context of access to services is a common example of the way through the HttpContext request:

 

 var obj = HttpContext.RequestServices.GetService(typeof(Type));

 

Above this way, in fact, is an anti-pattern, the official also avoid using, so much nonsense, hands-line and automatically inject a property characteristic class: PropertyFromServiceAttribute

 

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public class PropertyFromServiceAttribute : Attribute, IBindingSourceMetadata { public BindingSource BindingSource => BindingSource.Services; }

 

No extra code that can be labeled as AttributeTargets.Property

Applied to class members

 

    [Route("home")]
    [ApiController]
    public class HomeController : ControllerBase { [PropertyFromService] public IConfiguration Configuration { get; set; } [PropertyFromService] public IHostingEnvironment Environment { get; set; } [PropertyFromService] public CarService CarService { get; set; } [PropertyFromService] public PostServices PostServices { get; set; } [PropertyFromService] public TokenService TokenService { get; set; } [PropertyFromService] public TopicService TopicService { get; set; } [PropertyFromService] public UserService UserService { get; set; } public HomeController() { } [HttpGet("index")] public ActionResult<string> Index() { return "Hello world!"; } }

 

Please answer out loud, the above code is not very clean and tidy! However, like the use of injected above property has a small problem, before the object is not initialized, this property is null, meaning the class constructor, the member variable is not available, but it does not matter, this little problem by fully available constructor injection solve; more importantly, not every instance needs to use the constructor, is not it.

 

Sample Code

 

Hosted on Github  https://github.com/lianggx/Examples/tree/master/Ron.DI

Guess you like

Origin www.cnblogs.com/Leo_wl/p/11100095.html