如何使用DI在Class Constructor中获取Microsoft.AspNet.Http.HttpContext实例
我正在MVC 6中构建一个一次性应用程序,并尝试使用不同的依赖架构。
我面临的问题是如何创建特定于应用程序的自定义“ MyAppContext
”对象。 这将需要来自HttpContext
一些信息和来自数据库的一些信息,并且将是针对应用程序特定属性的请求范围的存储库。 我想将HttpContext
的实例传递给’ MyAppContext
‘的构造函数。
我已经使用DI成功创建了一个带有IDataService
接口的’ DataService
‘对象,这IDataService
用。 与’MyAppContext’类的不同之处在于它在构造函数中有两个参数–‘ DataService
‘和Microsoft.AspNet.Http.HttpContext
。 这是MyAppContext类:
public class MyAppContext : IMyAppContext { public MyAppContext(IDataService dataService, HttpContext httpContext) { //do stuff here with the httpContext } }
在启动代码中,我注册了DataService实例和MyAppContext实例:
public void ConfigureServices(IServiceCollection services) { services.AddMvc(); //adds a singleton instance of the DataService using DI services.AddSingleton(); services.AddScoped(); } public void Configure(IApplicationBuilder app) { app.UseErrorPage(); app.UseRequestServices(); app.UseMvc(routes => /* routes stuff */); }
我期望构造函数中的HttpContext
参数能够被DI解析。 运行代码时,这是我返回的exception:
InvalidOperationException:尝试激活“MyAppContext”时无法解析类型“Microsoft.AspNet.Http.HttpContext”的服务
我认为这是因为没有特定的HttpContext
实例发生此错误,但我不知道如何在DI中注册HttpContext
实例。 我添加了’ app.UseRequestServices();
‘但这没有任何区别。 我也试过了一个变种:
services.AddScoped();
但这失败了,因为第二个HttpContext
应该是一个实例 – 我知道它不正确但是无法弄清楚它是什么。
因此,总结一下 – 如何将HttpContext
对象传递给MyAppContext的构造函数?
在构造函数中注入IHttpContextAccessor
通过在组件中注入HttpContext
您违反了SOLID原则 。 更具体地说,你违反了:
这两种违规都会使测试代码变得更加困难。 虽然您可以像@victor建议的那样注入IHttpContextAccessor
,但这仍然违反了DIP和ISP,因为这是框架提供的抽象,您仍然依赖于HttpContext。 根据DIP,客户应该定义抽象。 这会导致您的代码不必要地耦合到框架。
相反,你应该努力指定狭窄的角色接口; 为您执行特定于您的应用程序需求的特定事物的接口。 注入一个包含字符串值的大字典(就像HttpContext
,从来都不是非常具体)。 根据您的问题,我们不清楚您需要从我们的MyAppContext
哪种数据,但我希望有类似当前登录用户的信息。 为此,您可以定义特定的IUserContext
抽象,例如:
public interface IUserContext { IPrincipal CurrentUser { get; } }
可以为此抽象轻松创建将应用程序连接到ASP.NET框架的适配器:
sealed class AspNetUserContextAdapter : IUserContext { private readonly IHttpContextAccessor accessor; public AspNetUserContextAdapter(IHttpContextAccessor accessor) { this.accessor = accessor; } public IPrincipal CurrentUser => accessor.HttpContext.User; }
此适配器确实依赖于IHttpContextAccessor
,但这没关系,因为适配器是位于Composition Root中的基础结构组件。 注册这个类有几种方法,例如:
services.AddSingleton();
在启动类中:
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc.Core; using Microsoft.Extensions.DependencyInjection; public void ConfigureServices(IServiceCollection services) { services.AddSingleton(); services.AddMvcCore(); }
在控制器中:
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc.Core; private readonly IHttpContextAccessor _httpContextAccessor; public ServerSentEventController(IHttpContextAccessor httpContextAccessor) { _httpContextAccessor = httpContextAccessor; }
为什么要在构造函数中传递HttpContext? 为什么不在任何地方直接访问它?
上述就是C#学习教程:如何使用DI在Class Constructor中获取Microsoft.AspNet.Http.HttpContext实例分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
public MyAppContext(IDataService dataService) { HttpContext mycontext = HttpContext.Current; //do stuff here with mycontext }
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/999846.html