Shotcut
Если тип контента JSON и вы используете Newtonsoft. Json, вы можете десериализовать вашу модель с внедрением зависимостей с помощью специального обработчика контрактов.
Привязка модели
В противном случае, если вам требуется поддержка других типов контента и т. Д. c, вам необходимо go сложным способом.
Для уточнения c модель или только модели FromBody
:
Используйте подшивку модели и выполните внедрение свойства. См. мой ответ пару недель a go.
Для универсальных c моделей или моделей из других источников:
Вам нужен пользовательский модель связующего провайдера. В поставщике связывателей моделей вы можете перебирать существующие поставщики связывателей моделей, находить связыватель модели для текущего контекста связывания модели, а затем украшать его собственным декоратором связывателя модели, который может выполнять DI для моделей.
Например, :
public class DependencyInjectionModelBinderProvider : IModelBinderProvider
{
public IModelBinder GetBinder(ModelBinderProviderContext context)
{
// Get MVC options.
var mvcOptions = context.Services.GetRequiredService<IOptions<MvcOptions>>();
// Find model binder provider for the current context.
IModelBinder binder = null;
foreach (var modelBinderProvider in mvcOptions.Value.ModelBinderProviders)
{
if (modelBinderProvider == this)
{
continue;
}
binder = modelBinderProvider.GetBinder(context);
if (binder != null)
{
break;
}
}
return binder == null
? null
: new DependencyInjectionModelBinder(binder);
}
}
// Model binder decorator.
public class DependencyInjectionModelBinder : IModelBinder
{
private readonly IModelBinder _innerBinder;
public DependencyInjectionModelBinder(IModelBinder innerBinder)
{
_innerBinder = innerBinder;
}
public async Task BindModelAsync(ModelBindingContext bindingContext)
{
await _innerBinder.BindModelAsync(bindingContext);
if (bindingContext.Result.IsModelSet)
{
var serviceProvider = bindingContext.HttpContext.RequestServices;
// Do DI stuff.
}
}
}
// Register your model binder provider
services.AddControllers(opt =>
{
opt.ModelBinderProviders.Insert(
0, new DependencyInjectionModelBinderProvider());
});
Это работает для внедрения свойства.
Для внедрения в конструктор, потому что создание модели все еще происходит во внутренней связке модели, вам определенно нужно больше кода, чем в этом примере, и у меня есть не пытался заставить инжектор конструктора работать в этом случае.