【问题标题】:How to use dependency injection in ASP.NET Core 2.0 for IHttpcontextAccessor如何在 ASP.NET Core 2.0 中为 IHttpcontextAccessor 使用依赖注入
【发布时间】:2018-10-17 06:05:23
【问题描述】:

我想设置一个服务来将当前的HttpContext 注入我项目的一个类中,以便它可以管理 cookie。

我在我的 Startup.cs 类中设置了这样的服务:

public void ConfigureServices(IServiceCollection services)
{
    services.AddHttpContextAccessor();
    services.TryAddSingleton<IActionContextAccessor, ActionContextAccessor>();
    services.AddMvc();
}

如何在 C# 类中使用此服务?

我的尝试是这样的:

我的班级操作cookies,我要注入当前的HttpContext

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Session;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace grupoveiculos.Infraestrutura.Session
{
    public class Cookie
    {
        private readonly IHttpContextAccessor _accessor;

        public Cookie(IHttpContextAccessor accessor)
        {
            _accessor = accessor;
        }

        public void Set(string chave, string valor, int? dataExpiracao)
        {
            CookieOptions option = new CookieOptions();

            if (dataExpiracao.HasValue)
                option.Expires = DateTime.Now.AddMinutes(dataExpiracao.Value);
            else
                option.Expires = DateTime.Now.AddMilliseconds(10);

            _accessor.HttpContext.Response.Cookies.Append(chave, valor, option);
        }
    }
}

但是当我尝试在控制器中实例化我的Cookie 类时,它会说“没有与所需的形参访问器相对应的参数”。该错误非常合乎逻辑,它需要构造函数参数。但我希望IHttpContextAccessor 被注入,而不是我必须提供参数。

在我的控制器中我尝试过:

[HttpGet]
[Route("SelecionarIdioma")]
public IActionResult SelecionarIdioma(string cultura)
{
    Cookie cookie = new Cookie(); // expecting the accessor parameter
    cookie.Set("idioma", cultura, 60);

    return RedirectToAction("Index", "Grupo");
}

【问题讨论】:

    标签: c# asp.net-core dependency-injection asp.net-core-2.0


    【解决方案1】:

    试试这个:

    var cookie = new Cookie(this.HttpContext.RequestServices.GetService<IHttpContextAccessor>());
    

    另一种方法是注册Cookie 类本身,然后将其注入构造函数。

    【讨论】:

      【解决方案2】:

      有几种不同的方法可以做到这一点,当你希望一个类能够使用依赖注入时,它需要注册,但是我相信所有控制器都应该在 MVC 应用程序中自动注册。

      尝试将其注入控制器而不是直接注入 Cookie。

      public class MyController : Controller 
      {
          private IHttpContextAccessor _accessor;
      
          public MyController(IHttpContextAccessor accessor)
          {
              _accessor = accessor;
          }
      
          [HttpGet]
          [Route("SelecionarIdioma")]
          public IActionResult SelecionarIdioma(string cultura)
          {
              Cookie cookie = new Cookie(_accessor);
          }
      }
      

      【讨论】:

      • 是的,我实现了该解决方案并且我喜欢它。我可能会坚持下去。
      【解决方案3】:

      这似乎是XY problem

      当您在控制器操作中已经可以访问响应时,真的不需要访问 IHttpContextAccessor 来访问响应

      你可以创建一个扩展方法来简化事情

      public static void AddCookie(this HttpResponse response, string chave, string valor, int? dataExpiracao) {
          CookieOptions option = new CookieOptions();
      
          if (dataExpiracao.HasValue)
              option.Expires = DateTime.Now.AddMinutes(dataExpiracao.Value);
          else
              option.Expires = DateTime.Now.AddMilliseconds(10);
      
          response.Cookies.Append(chave, valor, option);
      }
      

      并从控制器操作中调用它。

      [HttpGet]
      [Route("SelecionarIdioma")]
      public IActionResult SelecionarIdioma(string cultura) {
          Response.AddCookie("idioma", cultura, 60); //<-- extension method.    
          return RedirectToAction("Index", "Grupo");
      }
      

      【讨论】:

      • 是的,这很有意义。我经常使用扩展方法,我不知道为什么我没有提出这个想法。当今的框架有很多功能,您有时会迷失方向。
      猜你喜欢
      • 2023-03-12
      • 2018-08-23
      • 2022-07-07
      • 2018-03-23
      • 2018-03-03
      • 2016-09-27
      • 2017-01-01
      • 2018-01-16
      • 2019-02-22
      相关资源
      最近更新 更多