Внедрение зависимостей в ASP.NET Core MVC
В этой статье мы собираемся обсудить важную концепцию ASP.NET Core MVC — внедрение зависимостей .
Если вы пропустили некоторые из предыдущих статей серии, рекомендуем посетить страницу серии: серия ASP.NET Core MVC.
Чтобы загрузить исходный код этой статьи, посетите: Внедрение зависимостей в ASP.NET Core MVC.
Итак, давайте приступим к делу.
Инверсия зависимостей и внедрение зависимостей
Dependency Inversion
— это один из основных принципов разработки программного обеспечения, который мы используем для создания слабо связанных модулей. При создании приложений мы можем добиться этого с помощью техники, называемой Dependency Injection
. Dependency Injection (DI)
это метод внедрения зависимых модулей в наши классы.
Мы подробно обсуждали это в одной из наших других статей Принцип инверсии зависимостей . Мы также обсудили концепцию внедрения зависимостей и способы ее реализации.
Итак, в этом разделе мы рассмотрим поддержку внедрения зависимостей в приложении ASP.NET Core MVC.
Внедрение зависимостей в контроллеры
ASP.NET Core поддерживает внедрение зависимостей (DI) между классами и их зависимостями. Контроллеры MVC явно запрашивают зависимости через конструкторы. Кроме того, ASP.NET Core имеет встроенную поддержку внедрения зависимостей, что упрощает тестирование и обслуживание приложения.
Мы добавляем службы в качестве параметра конструктора, и среда выполнения разрешает службу из контейнера службы. Обычно мы определяем службы с помощью интерфейсов.
Когда мы реализуем шаблон репозитория в приложении ASP.NET Core MVC, мы используем внедрение зависимостей в наших контроллерах. Мы объяснили, как реализовать простой репозиторий данных, в разделе статьи Реализация простого репозитория данных .
Давайте создадим приложение ASP.NET Core MVC и реализуем простой репозиторий данных, как описано в статье.
Прежде всего, давайте создадим интерфейс IDataRepository
:
public interface IDataRepository
{
IEnumerable GetAll();
void Add(Employee employee);
}
Затем создадим класс, EmployeeManager
реализующий IDataRepository
интерфейс:
public class EmployeeManager : IDataRepository
{
public void Add(Employee employee)
{
throw new NotImplementedException();
}
IEnumerable IDataRepository.GetAll()
{
return new List() {
new Employee(){ }
};
}
}
Следующим шагом является добавление службы в контейнер службы. Нам нужно сделать это в ConfigureServices()
методе Startup.cs
класса:
services.AddScoped<IDataRepository<Employee>, EmployeeManager>();
Таким образом, мы настроили репозиторий с помощью внедрения зависимостей.
Далее создадим метод действия EmployeeController
with Index()
, чтобы получить список всех сотрудников:
public class EmployeeController : Controller
{
private readonly IDataRepository _dataRepository;
public EmployeeController(IDataRepository dataRepository)
{
_dataRepository = dataRepository;
}
public IActionResult Index()
{
IEnumerable employees = _dataRepository.GetAll();
return View(employees);
}
}
Здесь мы сначала объявляем _dataRepository
переменную типа IDataRepository
. Позже мы внедряем его через конструктор.
Мы также можем внедрить службу непосредственно в метод действия без использования внедрения конструктора. Для этого мы можем использовать [FromServices]
атрибут:
public IActionResult Index([FromServices] IDataRepository _dataRepository)
{
IEnumerable employees = _dataRepository.GetAll();
return View(employees);
}
Атрибут FromServices
указывает, что параметр действия должен быть привязан с помощью служб запроса.
Большой. Мы узнали, как использовать внедрение зависимостей для предоставления зависимостей в контроллер.
Теперь давайте посмотрим, как внедрить зависимости в представления.
Внедрение зависимостей в представления
ASP.NET Core поддерживает внедрение зависимостей в представления.
Когда внедрять зависимости в представления
Внедрение сервисов в представления является отклонением от концепции MVC. Но в некоторых случаях у нас могут быть сервисы для конкретных представлений, которые возвращают данные, которые мы используем только для заполнения элементов представления. Примером может служить служба, которая предоставляет набор значений, которые нам нужно отобразить в элементе управления списком. В таких сценариях мы можем внедрять сервисы непосредственно в представления. Внедрение представления может быть полезно для заполнения параметров в элементах пользовательского интерфейса, таких как раскрывающиеся списки.
Рассмотрим форму для создания книги, которая включает параметры для указания жанра. Для рендеринга данных с использованием стандартного подхода MVC контроллер должен запросить службы доступа к данным для этого набора параметров, а затем заполнить Model или ViewBag набором параметров, которые необходимо привязать.
Альтернативный подход заключается в внедрении сервисов непосредственно в представление. Этот подход сводит к минимуму количество кода, необходимого контроллеру, поскольку мы перемещаем логику построения элемента представления в само представление.
Как внедрять сервисы в представления
Мы можем внедрить службу в представление с помощью @inject
директивы. @inject
добавляет свойство в наше представление и инициализирует его с помощью DI:
@inject
Давайте создадим метод действия контроллера для отображения формы создания книги:
public class BooksController : Controller
{
public IActionResult Create()
{
return View();
}
}
Затем давайте создадим Bookкласс модели:
public class Book
{
public int Id { get; set; }
[Display(Name = "Book Title")]
public string Title { get; set; }
public string Genre { get; set; }
[DataType(DataType.Currency)]
[Range(1, 100)]
public decimal Price { get; set; }
[Display(Name = "Publish Date")]
[DataType(DataType.Date)]
public DateTime PublishDate { get; set; }
}
Для следующего шага давайте определим a BooksLookupServiceдля предоставления данных списка для жанров:
public class BooksLookupService
{
public List GetGenres()
{
return new List()
{
"Fiction",
"Thriller",
"Comedy",
"Autobiography"
};
}
}
Затем давайте создадим представление и внедрим в него экземпляр BooksLookupService
:
@model WorkingWithDI.Models.Book
@inject WorkingWithDI.Models.Services.BooksLookupService BooksLookupService
@{
ViewData["Title"] = "Create";
var genres = BooksLookupService.GetGenres();
}
<h1>Create</h1>
<h4>Book</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="Create">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Title" class="control-label"></label>
<input asp-for="Title" class="form-control" />
<span asp-validation-for="Title" class="text-danger"></span>
</div>
<div>
<label asp-for="Genre" class="control-label"></label>
<select asp-items="@(new SelectList(genres))" class="form-control" ></select>
</div>
<div class="form-group">
<label asp-for="Price" class="control-label"></label>
<input asp-for="Price" class="form-control" />
<span asp-validation-for="Price" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="PublishDate" class="control-label"></label>
<input asp-for="PublishDate" class="form-control" />
<span asp-validation-for="PublishDate" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
</div>
<div>
<a asp-action="Index">Back to List</a>
</div>
Это предоставит значения списка в представление.
В качестве последнего шага нам нужно зарегистрировать типы, которые мы запрашиваем через внедрение зависимостей, в Startup.ConfigureServices()
. Если тип не зарегистрирован, он генерирует исключение времени выполнения.
services.AddTransient<BooksLookupService>();
Вот и все. Теперь давайте запустим приложение и перейдем к Create Books
форме:
Мы видим, что список жанров заполняется путем получения значений из файла BooksLookupService
.
Отлично, мы научились внедрять зависимость прямо в представление.
Вывод
В этой статье мы изучили следующие темы:
- Принцип инверсии зависимостей и как этого добиться с помощью внедрения зависимостей
- Внедрение зависимостей в контроллеры
- Внедрение зависимостей в представления приложения ASP.NET Core MVC
В следующей части этой серии мы узнаем о модульном тестировании в ASP.NET Core MVC .
Только полноправные пользователи могут оставлять комментарии. Аутентифицируйтесь пожалуйста, используя сервисы.