繁体   English   中英

将IHttpContextAcessor注入到控制器动作内的绑定模型中

[英]Injecting IHttpContextAcessor into a Binding Model inside an Controller Action

我有一个控制器操作方法:

public void Register([FromBody]RegisterTenantCommand message)
{
    ...
}

我有带有构造函数的RegisterTenantCommand

public class RegisterTenantCommand
{
    public RegisterTenantCommand(IHttpContextAccessor httpContextAccessor)
        : base(httpContextAccessor) { }
}

但是,当我启动我的应用程序并执行此操作时,我有httpContextAccessor = null

我该如何解决?

似乎您在将命令与UI框架中的命令混淆(例如ICommand接口的WPF + MVVM实现)。

当前的实现还违反了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关系,对于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手动注册(这里我将使用内置):

services.AddTransient<ICommandHandler<RegisterTenantCommand>, RegisterTenantCommandHandler>();

您可以在操作中或在控制器中或任何其他服务中注入它:

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) ,其实generalCommandHandler.Handle(command)解析并处理它。

默认情况下,不再注册IHttpContextAccessor服务(不再)

IHttpContextAccessor可用于访问当前线程的HttpContext。 但是,保持此状态将带来不小的性能成本,因此已将其从默认服务集中删除。

依赖它的开发人员可以根据需要将其添加回:
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

有关讨论,请参见aspnet / Hosting#793

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM