ASP.NET Core - IModelBinder - Контроллер доступа DbContext

У меня есть решение MVC на основе ASP.NET 2 с универсальным контроллером и настраиваемым связывателем.

Код контроллера следующий:

public class GenericController<T> : Controller where T : BaseModel
{
    public readonly AppContext Db = new AppContext();

    ...

    public virtual ActionResult Edit([ModelBinder(typeof(MyCustomBinder))] T obj)

Итак, в основном, когда я вызываю действие Edit, вызывается класс MyCustomBinder.

MyCustomBinderClass (который наследуется от DefaultModelBinder) необходимо переопределить:

protected override PropertyDescriptorCollection GetModelProperties(ControllerContext controllerContext, ModelBindingContext bindingContext)
protected override void BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor)

и оба метода имеют ссылку на «вызывающий» контроллер.

Итак, я могу получить доступ к DbContext контроллера:

dynamic controller = controllerContext.Controller;
dynamic db = controller.Db;

--

Теперь я перехожу на ядро ​​ASP.NET. Чтобы создать настраиваемый связыватель, мне нужно реализовать IModelBinder, поэтому мне нужно реализовать:

public Task BindModelAsync(ModelBindingContext bindingContext)

Вопрос в том, как мне получить доступ к DbContext вызывающего контроллера?

Мне это нужно для выполнения операций с данными БД.

Первая идея заключалась в том, чтобы иметь только один контекст в моем приложении, что явно неверно (и приводит к ошибкам времени выполнения).

Но мне по-прежнему нужен один и тот же контекст как в вызывающем контроллере, так и в настраиваемом связывателе; в противном случае это также приводит к ошибкам из-за того, что объекты изменяются в двух разных контекстах.

Есть идеи, как это решить?

Спасибо!


person Guido Lo Spacy    schedule 10.10.2017    source источник


Ответы (1)


Я бы рекомендовал вместо того, чтобы создавать DbContext вручную, получить его экземпляр из инъекции зависимостей.

С учетом сказанного, вы можете легко получить DbContext через инъекцию конструктора.

public class MyCustomBinder : IModelBinder
{
    private readonly AppDbContext _dbContext;

    public MyCustomBinder(AppDbContext dbContext)
    {
        _dbContext = dbContext;
    }

    public Task BindModelAsync(ModelBindingContext bindingContext)
    {
        ...
    }
}
person David Liang    schedule 11.10.2017