使用 ModelState 进行依赖注入
Dependency Injection with ModelState
首先,我知道在服务中使用 ModelState 通常不受欢迎,因为它将服务与 Mvc 框架紧密耦合。在我们的例子中,这不是问题,但我最终确实计划迁移到 IValidationDictionary 和 ModelState 包装器,但现在需要这一步才能工作。
现在,关于这个问题,这位很酷的家伙:
public class BaseService : IBaseService
{
protected MIRTContext _context;
protected IMapper _mapper;
//TODO: This tightly couples .NET MVC to our services.
// Could be imporoved with an interface and a ModelState wrapper
// in order to decouple.
private ModelStateDictionary _modelState;
public BaseService(
MIRTContext context,
IMapper mapper,
ModelStateDictionary modelState
) {
_context = context;
_mapper = mapper;
_modelState = modelState;
}
async Task<bool> IBaseService.SaveContext() {
if(_modelState.IsValid) {
try {
await _context.SaveChangesAsync();
return true;
}
catch {
return false;
}
}
else {
return false;
}
}
}
它一直给我这个错误:
Unable to resolve service for type 'Microsoft.AspNetCore.Mvc.ModelBinding.ModelStateDictionary' while attempting to activate
我假设我在 Startup.cs 的 ConfigureServices 中缺少某种 AddSingleton 东西,但我似乎无法弄清楚是什么。任何人都知道如何将其正确注入依赖项?
ModelState
无法通过依赖注入获得,但您可以使用 IActionContextAccessor
, which provides access to the current ActionContext
and its ModelState
属性.
首先,您需要为DI注册IActionContextAccessor
:
services.AddSingleton<IActionContextAccessor, ActionContextAccessor>();
接下来,更新您的 BaseService
class 以使用它:
public class BaseService : IBaseService
{
// ...
private readonly IActionContextAccessor _actionContextAccessor;
public BaseService(
// ...
IActionContextAccessor actionContextAccessor
) {
// ...
_actionContextAccessor = actionContextAccessor;
}
async Task<bool> IBaseService.SaveContext() {
var actionContext = _actionContextAccessor.ActionContext;
if (actionContext.ModelState.IsValid) {
// ...
}
else {
return false;
}
}
}
请注意,如果对 SaveContext
的调用在 MVC 及其控制器、过滤器等之外,则上面的 actionContext
将是 null
首先,我知道在服务中使用 ModelState 通常不受欢迎,因为它将服务与 Mvc 框架紧密耦合。在我们的例子中,这不是问题,但我最终确实计划迁移到 IValidationDictionary 和 ModelState 包装器,但现在需要这一步才能工作。
现在,关于这个问题,这位很酷的家伙:
public class BaseService : IBaseService
{
protected MIRTContext _context;
protected IMapper _mapper;
//TODO: This tightly couples .NET MVC to our services.
// Could be imporoved with an interface and a ModelState wrapper
// in order to decouple.
private ModelStateDictionary _modelState;
public BaseService(
MIRTContext context,
IMapper mapper,
ModelStateDictionary modelState
) {
_context = context;
_mapper = mapper;
_modelState = modelState;
}
async Task<bool> IBaseService.SaveContext() {
if(_modelState.IsValid) {
try {
await _context.SaveChangesAsync();
return true;
}
catch {
return false;
}
}
else {
return false;
}
}
}
它一直给我这个错误:
Unable to resolve service for type 'Microsoft.AspNetCore.Mvc.ModelBinding.ModelStateDictionary' while attempting to activate
我假设我在 Startup.cs 的 ConfigureServices 中缺少某种 AddSingleton 东西,但我似乎无法弄清楚是什么。任何人都知道如何将其正确注入依赖项?
ModelState
无法通过依赖注入获得,但您可以使用 IActionContextAccessor
, which provides access to the current ActionContext
and its ModelState
属性.
首先,您需要为DI注册IActionContextAccessor
:
services.AddSingleton<IActionContextAccessor, ActionContextAccessor>();
接下来,更新您的 BaseService
class 以使用它:
public class BaseService : IBaseService
{
// ...
private readonly IActionContextAccessor _actionContextAccessor;
public BaseService(
// ...
IActionContextAccessor actionContextAccessor
) {
// ...
_actionContextAccessor = actionContextAccessor;
}
async Task<bool> IBaseService.SaveContext() {
var actionContext = _actionContextAccessor.ActionContext;
if (actionContext.ModelState.IsValid) {
// ...
}
else {
return false;
}
}
}
请注意,如果对 SaveContext
的调用在 MVC 及其控制器、过滤器等之外,则上面的 actionContext
将是 null