Reputation: 5896
First, I am aware that using ModelState in a service is typically frowned upon because it tightly couples the service to the Mvc framework. In our case, this isn't a problem, but I do eventually have plans to migrate to an IValidationDictionary and a ModelState wrapper, but need this step to work for now.
Now, on to the issue, this cool guy right here:
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;
}
}
}
It keeps giving me this error:
Unable to resolve service for type 'Microsoft.AspNetCore.Mvc.ModelBinding.ModelStateDictionary' while attempting to activate
I'm assuming I'm missing some sort of AddSingleton thing in my ConfigureServices in Startup.cs but I can't seem to figure out what. Anyone know how to get this to dependency inject properly?
Upvotes: 1
Views: 1145
Reputation: 93203
ModelState
isn't available via Dependency Injection, but you can use IActionContextAccessor
, which provides access to the current ActionContext
and its ModelState
property.
First, you need to register IActionContextAccessor
for DI:
services.AddSingleton<IActionContextAccessor, ActionContextAccessor>();
Next, update your BaseService
class to use it:
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;
}
}
}
Note that actionContext
above will be null
if the call to SaveContext
is outside of MVC and its controllers, filters, etc.
Upvotes: 3