Есть ли лучший способ добавить dbcontext к контроллеру Asp .core MVC? - PullRequest
1 голос
/ 16 июня 2020

В новом MVC Core кажется, что стандартный способ получить контекст для контроллера - это сделать это

public class BaseController : Controller
    {

        public readonly ReportDBContext _db;

        public BaseController(ReportDBContext db)
        {
            _db = db;
        }
}

Затем я могу использовать

public class HomeController : BaseController
    {

        public HomeController(ReportDBContext db) : base(db) { }
}

Чтобы сделать это немного проще для всех остальных контроллеров. Обычно в Asp. net MVC я могу получить контекст в любое время, используя new ReportDBContext()

Есть ли аналогичный способ сейчас, или мне нужно иметь контекст во всех контроллерах в asp .core MVC?

Ответы [ 3 ]

2 голосов
/ 16 июня 2020

Архитектура ASP. NET Core построена на внедрении зависимостей. У него даже есть встроенный контейнер для внедрения зависимостей, но вы также можете использовать другие, такие как AutoFa c или NInject. Если вам нужен DbContext более чем в одном действии, вы можете использовать инъекцию конструктора, как в вашем примере.

Если он вам нужен только один раз, вы можете вставить его прямо в метод действия следующим образом:

public IActionResult Get([FromServices]ReportDbContext db) 
{ 
   …
} 

Использование внедрения зависимостей делает ваш код более тестируемым. Для своих модульных тестов вы можете внедрить InMemory DbContext.

На мой взгляд, это еще меньше работы, чем создание DbContext самостоятельно. Это делается фреймворком.

2 голосов
/ 16 июня 2020

Благодаря ответу @ mm8 , если вы решили использовать внедрение зависимостей, вы можете выполнить следующие шаги.

Предположим, вы определили свой ReportDBContext like это:

public class ReportDBContext : DbContext
{
    public DbSet<Sample> Samples { get; set; }
    //...

    public ReportDBContext(DbContextOptions<ReportDBContext> options) : base(options) 
    { 
      //...
    }
}

Итак, вам нужно настроить свой startup.cs следующим образом:

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        //...What needed
        services.AddDbContext<ReportDBContext>(options => options.UseSqlServer("Connection string to your DB"));
        //...What needed
    }
    //...
 }

Таким образом, вы можете легко ввести свой ReportDBContext в свои классы, как это (например, ввести его на один из ваших контроллеров):

[Route("api/[controller]")]
public class ValuesController : Controller
{
    private readonly ReportDBContext _dbContext;

    public ValuesController(ReportDBContext dbContext )
    {
        _dbContext = dbContext;
    }
    //...
}

Вы можете просто ввести ReportDBContext в свой BaseController вместо того, чтобы вводить его также в каждый контроллер в вашем проекте.

Обновление 1

Если вы не хотите вставлять ReportDBContext в каждый конструктор, вы можете создать свой BaseController следующим образом, используя HttpContext.RequestServices:

public class BaseController : Controller
{
    protected ReportDBContext DbContext => (ReportDBContext)HttpContext.RequestServices.GetService(typeof(ReportDBContext));
    //...
}

[Route("api/[controller]")]
public class ValuesController : BaseController
{
    //...

    [HttpGet]
    public List<Sample> Get() => DbContext.Samples.ToList();
}

Подробнее здесь:

  1. https://docs.microsoft.com/en-us/ef/core/miscellaneous/configuring-dbcontext
  2. http://www.binaryintellect.net/articles/17ee0ba2-99bb-47f0-ab18-f4fc32f476f8.asp

Вы будете также необходимо установить как минимум эти два пакета NuGet:

  1. Microsoft.EntityFrameworkCore
  2. Microsoft.EntityF rameworkCore.SqlServer (если поставщиком базы данных является Microsoft SQL Server)
2 голосов
/ 16 июня 2020

Обычно в Asp. net MVC Я могу получить контекст в любое время, используя new ReportDBContext () ...

Вы можете сделать то же самое, т.е. в настоящее время явно создавать новый контекст в контроллере. Вам ничего не мешает сделать это, за исключением лучших практик.

Некоторые из преимуществ использования внедрения зависимостей заключаются в том, что вы можете определить время жизни зависимости в классе Startup и повторно использовать его в все ваши контроллеры и что вы можете высмеивать зависимости в своих модульных тестах. Пожалуйста, обратитесь к docs и к этому вопросу для получения дополнительной информации.

Но вы определенно не должны использовать инъекцию зависимостей, если вы не не хочу или не имею причин не делать этого. Компилятор не заставляет вас определять настраиваемый конструктор, принимающий зависимость.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...