我有一个控制器操作方法:
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)
,其实现将解析并处理它。关于c# - 将IHttpContextAccessor注入(inject)到 Controller Action 内的绑定(bind)模型中,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40338470/