在Controller Action中的绑定模型中注入ihttpcontextaccessor
本文关键字:模型 注入 ihttpcontextaccessor 绑定 Controller Action | 更新日期: 2023-09-27 18:15:33
我有一个控制器动作方法:
public void Register([FromBody]RegisterTenantCommand message)
{
...
}
我有类RegisterTenantCommand与构造器:
public class RegisterTenantCommand
{
public RegisterTenantCommand(IHttpContextAccessor httpContextAccessor)
: base(httpContextAccessor) { }
}
但是当我启动我的应用程序并执行此操作时,我有httpContextAccessor = null。
如何解决这个问题?
似乎您将命令与UI框架的命令混淆(如WPF+MVVM实现的ICommand
接口)。
当前的实现也违反了SRP原则,即一个类应该只负责一件事。你基本上是处理输入(将其绑定到用户值)并执行它,以及处理其中的执行逻辑。
命令/处理器或CQRS模式中的命令仅仅是消息,它们只包含数据(这些数据可能被序列化,也可能不被序列化,并通过消息总线发送给其他后台进程处理)。
// ICommand is a marker interface, not to be confused with ICommand from WPF
public class RegisterTenantCommand : ICommand
{
public string TenantId { get; set; }
public string Name { get; set; }
}
命令处理程序由一个标记接口和它的实现组成(1:1关系,一个命令对应一个处理程序)。
public interface ICommandHandler<T> where T : ICommand
{
void Handle(T command);
}
public class RegisterTenantCommandHandler : ICommandHandler<RegisterTenantCommand>
{
private readonly IHttpContext context;
// You should really abstract this into a service/facade which hides
// away the dependency on HttpContext
public RegisterTenantCommandHandler(IHttpContextAccessor contextAccessor)
{
this.context = contextAccesspor.HttpContext;
}
public void Handle(RegisterTenantCommand command)
{
// Handle your command here
}
}
在使用Autofac等第三方IoC时自动注册,或者使用内置IoC手动注册(这里我将使用内置IoC):
services.AddTransient<ICommandHandler<RegisterTenantCommand>, RegisterTenantCommandHandler>();
你可以在action、controller或任何其他service中注入它:
public class TenantController
{
public TenantController(ICommandHandler<RegisterTenantCommand> registerTenantHandler)
{
...
}
}
或动作
public Task<IActionResult> RegisterTenant(
[FromBody]RegisterTenantCommand command,
[FromService]ICommandHandler<RegisterTenantCommand> registerTenantHandler
)
{
registerTenantHandler.Handle(command);
}
当然,你可以进一步抽象它,只注入一个接口类来解析和处理所有的命令,然后叫它generalCommandHandler.Handle(command)
,它的实现将解析和处理它
IHttpContextAccessor服务默认不注册
IHttpContextAccessor可以用来访问当前线程。然而,维护这种状态具有重要的意义性能成本,因此它已从默认设置中删除服务。
依赖它的开发人员可以根据需要添加它:
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
请参阅aspnet/Hosting#793进行讨论。