Учебный проект на ASP.NET Core + MongoDB, демонстрирующий:
- работу с MongoDB в режиме Replica Set,
- использование транзакций при обновлении связанных коллекций (фильмы ↔ актёры),
- применение паттерна репозиторий,
- конфигурацию подключения к MongoDB через Options pattern,
- контейнеризацию с помощью Docker Compose.
- Структура контейнеров
- Volumes
- Networks
- Запуск проекта
- Скриншоты эндпоинтов в Swagger
- Работа с MongoDB
- Репозиторий данных (BaseRepository)
- Конфигурация и валидация настроек MongoDB
Проект разворачивается с помощью Docker Compose и состоит из трёх сервисов:
- Основное C# Web API приложение.
- Сборка из Dockerfile (
MongoDBTraining.WebApi/Dockerfile). - Подключается к MongoDB по строке:
mongodb://mongo1:27017/?replicaSet=rs0. - Использует базу данных
MovieDb. - Порт:
8080:8080. - Зависит от
mongo1иsetup-replica.
- Контейнер с MongoDB 7.0.
- Данные сохраняются в volume
mongo1_data. - Запускается в режиме реплика-сета:
mongod --replSet rs0 --bind_ip_all- Доступна на порту
27017. - Healthcheck выполняет команду:
mongosh --eval "db.adminCommand('ping')"- Вспомогательный контейнер для инициализации реплика-сета.
- Ждёт, пока
mongo1будет готов. - Инициализирует
rs0и проверяет, чтоmongo1стал primary. - Завершается после настройки.
mongo1_data— хранение данных MongoDB.
app-network— bridge-сеть для взаимодействия сервисов.
docker compose up -d --buildПосле запуска:
- Web API: http://localhost:8080
- MongoDB: mongodb://localhost:27017/?replicaSet=rs0
При выполнении этого действия используются транзакции MongoDB (только в режиме Replica Set).
Реализован ApplicationDbContext — класс, отвечающий за подключение и доступ к коллекциям MongoDB. Он создаёт и хранит объект базы данных (IMongoDatabase), который потом используется репозиториями.
- Обобщённый класс, реализующий интерфейс
IRepository<T>, гдеTнаследуется отBaseEntity. - Работает с коллекцией MongoDB через
IMongoCollection<T>. - Реализует базовые CRUD-операции.
- Все методы асинхронные.
- Возвращаемые коллекции оборачиваются в
IReadOnlyList<T>. - Через
IMongoClientможно работать с транзакциями и получать доступ к другим коллекциям.
AddActorToMovieAsync— добавляет актёра в фильм и обновляет обе коллекции в транзакции.DeleteAsync— удаляет фильм и убирает его Id из всех актёров.
DeleteAsync— удаляет актёра и убирает его Id из всех фильмов.
- Все операции обновления связанных коллекций выполняются через
ExecuteInTransactionAsyncизApplicationDbContext. - Используется
IClientSessionHandle; транзакции стартуют и коммитятся. - В случае ошибки транзакция откатывается.
- Работает только в режиме реплика-сета MongoDB.
public class MongoSettings
{
public required string ConnectionString { get; init; }
public required string DatabaseName { get; init; }
}public class MongoSettingsValidation : IValidateOptions<MongoSettings>
{
public ValidateOptionsResult Validate(string? name, MongoSettings options)
{
if (string.IsNullOrWhiteSpace(options.ConnectionString))
return ValidateOptionsResult.Fail(
$"MongoDB {nameof(MongoSettings.ConnectionString)} is missing in configuration");
if (string.IsNullOrWhiteSpace(options.DatabaseName))
return ValidateOptionsResult.Fail(
$"MongoDB {nameof(MongoSettings.DatabaseName)} is missing in configuration");
return ValidateOptionsResult.Success;
}
}public static IServiceCollection ConfigurePersistence(this IServiceCollection services, IConfiguration configuration)
{
services
.AddOptions<MongoSettings>()
.Bind(configuration.GetSection(nameof(MongoSettings)))
.ValidateOnStart();
services.AddSingleton<IValidateOptions<MongoSettings>, MongoSettingsValidation>();
services.AddSingleton<IMongoClient>(sp =>
{
var settings = sp.GetRequiredService<IOptions<MongoSettings>>().Value;
return new MongoClient(settings.ConnectionString);
});
services.AddScoped<ApplicationDbContext>();
services.AddScoped<IMovieRepository, MovieRepository>();
return services;
}