https://github.com/aasmirnov-webdev/mfti_csharp-developer_final_project
Выполнение финального проекта в рамках обучения по программе профессиональной переподготовки "C#-разработчик" в МФТИ
https://github.com/aasmirnov-webdev/mfti_csharp-developer_final_project
api asp-net-core-web-api backend clean-architecture csharp ddd dotnet solid
Last synced: about 2 months ago
JSON representation
Выполнение финального проекта в рамках обучения по программе профессиональной переподготовки "C#-разработчик" в МФТИ
- Host: GitHub
- URL: https://github.com/aasmirnov-webdev/mfti_csharp-developer_final_project
- Owner: AASmirnov-Webdev
- Created: 2025-09-21T00:03:08.000Z (9 months ago)
- Default Branch: master
- Last Pushed: 2025-09-21T01:15:32.000Z (9 months ago)
- Last Synced: 2025-09-21T03:11:22.883Z (9 months ago)
- Topics: api, asp-net-core-web-api, backend, clean-architecture, csharp, ddd, dotnet, solid
- Language: C#
- Homepage:
- Size: 41 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Финальный проект в рамках обучения по программе профессиональной переподготовки "C#-разработчик" в МФТИ
### Веб-приложение для автоматизации бизнес-процессов зоопарка с использованием Domain-Driven Design и Clean Architecture.
# Описание задания
### Вам предстоит разработать веб-приложение для автоматизации следующих бизнес-процессов зоопарка: управление животными; вольерами; расписанием кормлений.
В ходе общения с заказчиком были выявлены следующие требования к функциональности проектируемого модуля веб-приложения
`Use Cases`:
- Добавить / удалить животное
- Добавить / удалить вольер
- Переместить животное между вольерами
- Просмотреть расписание кормления
- Добавить новое кормление в расписание
- Просмотреть статистику зоопарка (кол-во животных, свободные вольеры и т.д.).
После встречи с доменными экспертами.
Вы определили три основных класса: `Animal`, `Enclosure` и `FeedingSchedule`. Архитектор проекта предложил вам следующий вариант создания богатой модели предметной области:
Животное (`Animal`)
- Вид, кличка, дата рождения, пол, любимая еда, статус (здоров/болен)
- Методы: кормить, лечить, переместить в другой вольер
Вольер (`Enclosure`)
- Тип (для хищников, травоядных, птиц, аквариум и т.д.), размер, текущее количество животных, максимальная вместимость
- Методы: добавить животное, убрать животное, провести уборку
Расписание кормления (`FeedingSchedule`)
- Животное, время кормления, тип пищи
- Методы: изменить расписание, отметить выполнение
Выявление `Value Object` оставили на ваше усмотрение.
На kickoff митинге с командой было приняли решение, в первую очередь, реализовать следующие сервисы:
- `AnimalTransferService` (для перемещения животных между вольерами)
- `FeedingOrganizationService` (для организации процесса кормления)
- `ZooStatisticsService` (для сбора статистики по зоопарку)
Определить и реализовать следующие доменные события:
- `AnimalMovedEvent` (при перемещении животного)
- `FeedingTimeEvent` (при наступлении времени кормления)
Определили следующую структуру проекта, согласно **Clean Architecture**:
- `Domain` (ядро, содержит наши модели)
- `Application` (содержит сервисы, реализующие бизнес-логику приложения)
- `Infrastructure` (внешние взаимодействия)
- `Presentation` (контроллеры нашего веб-приложения)
ТРЕБУЕТСЯ
1. Разработать классы доменной модели согласно концепции **Domain-Driven Design**
2. Построить структуру проекта соблюдая принципы **Clean Architecture**.
3. В слое представления (`Web API` в архитектурном стиле `REST API`) реализовать следующие контроллеры:
- Контроллер для работы с животными (просмотр информации о животных, добавление новых, удаление);
- Контроллер для работы с вольерами;
4. При помощи инструмента проектирования API (например `Swagger`) произвести тестирование нашего приложения:
- Добавить новые сущности (вольер, животное, расписание кормления);
- Получить информации о животных, вольерах и расписание кормления;
- Выполнить операции кормления, перемещения и т.д.
5. Хранение данных организовать в виде in-memory хранилища (`Infrastructure Layer`)
6. Написать отчет, в котором отразить:
- какие пункты из требуемого функционала вы реализовали и в каких классах \ модулях их можно увидеть.
- какие концепции **Domain-Driven Design** и принципы **Clean Architecture** вы применили, скажите в каких классах (модулях).
Критерии оценки
1. Реализация основных требований к функциональности
2. Соблюдение принципов **Clean Architecture**:
- Слои должны зависеть только внутрь (`Domain` не зависит ни от чего);
- Все зависимости между слоями через интерфейсы;
- Бизнес-логика полностью изолирована в `Domain` и `Application` слоях.
3. Соблюдены концепции **Domain-Driven Design**:
- Использование `Value Objects` для примитивов;
- Инкапсуляция бизнес-правил внутри доменных объектов.
4. Покрыто тестами более 65% кода.
# Реализация проектного решения
## Архитектура
- **Domain Layer**: Бизнес-логика и доменные модели
- **Application Layer**: Сервисы приложения
- **Infrastructure Layer**: Репозитории и данные
- **API Layer**: Web API контроллеры
## Функциональность
- Управление животными (добавление, удаление, перемещение)
- Управление вольерами
- Расписание кормлений
- Статистика зоопарка
## Технологии
- .NET 8.0
- ASP.NET Core Web API
- Swagger
- Clean Architecture
- Domain-Driven Design
## Установка и запуск через Visual Studio
1. Клонируйте репозиторий
2. Откройте `ZooManagement.sln`
3. Установите `API` как Startup Project
4. Нажмите F5 или Ctrl + F5
5. Перейдите: `https://localhost:7201/swagger`
## xUnit-Тестирование через Visual Studio
1. Откройте Test Explorer (Test → Test Explorer)
2. Нажмите "Run All Tests"
## Тестирование приложения через API Endpoints
Используйте Swagger UI для тестирования API endpoints после запуска:
- Swagger UI: `https://localhost:7201/swagger`
- Animals API: `https://localhost:7201/api/Animals`
- Enclosures API: `https://localhost:7201/api/Enclosures`
- Statistics API: `https://localhost:7201/api/Statistics`
## Отчет по проекту!
### 1. Реализованный функционал
Use Cases из задания:
a. Добавить / удалить животное:
- Контроллер: `AnimalsController` (POST /api/Animals, DELETE /api/Animals/{id})
- Сервис: `InMemoryAnimalRepository` (AddAsync, DeleteAsync)
- Модель: `Animal` entity
b. Добавить / удалить вольер
- Контроллер: `EnclosuresController` (POST /api/Enclosures, DELETE /api/Enclosures/{id})
- Сервис: `InMemoryEnclosureRepository` (AddAsync, DeleteAsync)
- Модель: `Enclosure` entity
c. Переместить животное между вольерами
- Контроллер: `AnimalsController` (POST /api/Animals/{id}/transfer/{enclosureId})
- Сервис: `AnimalTransferService` (TransferAnimal)
- Событие: `AnimalMovedEvent`
d. Просмотреть расписание кормления
- Контроллер: `FeedingSchedulesController` (GET /api/FeedingSchedules)
- Сервис: `InMemoryFeedingScheduleRepository` (GetAllAsync, GetByAnimalIdAsync)
- Модель: `FeedingSchedule` entity
e. Добавить новое кормление в расписание
- Контроллер: `FeedingSchedulesController` (POST /api/FeedingSchedules)
- Сервис: `FeedingOrganizationService` (ScheduleFeedingAsync)
- Модель: `FeedingSchedule` entity
f. Просмотреть статистику зоопарка
- Контроллер: `StatisticsController` (GET /api/Statistics/zoo, GET /api/Statistics/feeding)
- Сервис: `ZooStatisticsService` (GetStatistics)
- Сервис: `FeedingOrganizationService` (GetFeedingStatisticsAsync)
Дополнительный реализованный функционал:
- Отметка кормления как выполненного: `FeedingSchedulesController` (POST /api/FeedingSchedules/{id}/complete)
- Уборка вольеров: `EnclosuresController` (POST /api/Enclosures/{id}/clean)
- Просмотр предстоящих кормлений: `FeedingSchedulesController` (GET /api/FeedingSchedules/upcoming)
- Получение животных по ID: `AnimalsController` (GET /api/Animals/{id})
- Получение вольеров по ID: `EnclosuresController` (GET /api/Enclosures/{id})
Разработаны и успешно пройдены 12 Unit-тестов (Tests) примерно 70% покрытия кода
Описание тестов:
1. `Animal_Feed_Should_Raise_AnimalFedEvent` - проверяет генерацию события кормления
2. `Animal_Heal_Should_Set_IsHealthy_To_True` - проверяет лечение животного
3. `Enclosure_AddAnimal_Should_Increase_CurrentCapacity` - проверяет добавление животного в вольер
4. `Enclosure_AddAnimal_When_Full_Should_Throw_Exception` - проверяет обработку переполнения вольера
5. `FeedingSchedule_MarkAsCompleted_Should_Set_IsCompleted_To_True` - проверяет отметку кормления
6. `FeedingSchedule_Reschedule_Should_Change_FeedingTime` - проверяет изменение времени кормления
7. `AnimalTransferService_TransferAnimal_Should_Move_Animal_Successfully` - тестирует сервис перемещения
8. `AnimalTransferService_TransferAnimal_When_TargetEnclosure_Full_Should_Throw_Exception` - тестирует ошибки перемещения
9. `FeedingOrganizationService_ScheduleFeeding_Should_Create_FeedingSchedule` - тестирует создание расписания
10. `ZooStatisticsService_GetStatistics_Should_Return_Correct_Statistics` - тестирует статистику
11. `EntityBase_Equals_Should_Work_Correctly` - тестирует сравнение сущностей
12. `DomainEvent_Should_Have_Correct_Properties` - тестирует свойства событий
### 2. Примененные концепции **Domain-Driven Design** и **Clean Architecture**
### Clean Architecture:
1. Domain Layer (`Domain`)
- Сущности: `Animal`, `Enclosure`, `FeedingSchedule`, `EntityBase`
- События: `DomainEvent`, `AnimalMovedEvent`, `FeedingTimeEvent`, `AnimalFedEvent`, `FeedingCompletedEvent`
- Интерфейсы: `IAnimalRepository`, `IEnclosureRepository`, `IFeedingScheduleRepository`
- Принцип: Ядро системы не зависит от внешних слоев
2. Application Layer (`Application`)
- Сервисы: `AnimalTransferService`, `FeedingOrganizationService`, `ZooStatisticsService`
- DTO: `CreateAnimalRequest`, `CreateEnclosureRequest`, `CreateFeedingScheduleRequest`, `AnimalResponse`, `EnclosureResponse`
- Принцип: Содержит бизнес-логику приложения, зависит только от `Domain` Layer
3. Infrastructure Layer (`Infrastructure`)
Реализации репозиториев: `InMemoryAnimalRepository`, `InMemoryEnclosureRepository`, `InMemoryFeedingScheduleRepository`
Принцип: Реализация внешних зависимостей, зависит от `Domain` и `Application` Layers
4. Presentation Layer (`API`)
- Контроллеры: `AnimalsController`, `EnclosuresController`, `FeedingSchedulesController`, `StatisticsController`
- Принцип: Внешний интерфейс системы, зависит от `Application` Layer
### Domain-Driven Design:
1. Rich Domain Model
- Классы: `Animal`, `Enclosure`, `FeedingSchedule`
Поведение в сущностях:
- `Animal.Feed()`, `Animal.Heal()`, `Animal.MoveToEnclosure()`
- `Enclosure.AddAnimal()`, `Enclosure.RemoveAnimal()`, `Enclosure.Clean()`
- `FeedingSchedule.MarkAsCompleted()`, `FeedingSchedule.Reschedule()`
2. Aggregate Roots
- Сущности: `Animal`, `Enclosure`, `FeedingSchedule` как корни агрегатов
- Инварианты: `Enclosure.CanAddAnimal()` проверяет вместимость
3. Domain Events
- События: `AnimalMovedEvent`, `FeedingTimeEvent`, `AnimalFedEvent`, `FeedingCompletedEvent`
- Генерация: Вызываются через `AddDomainEvent()` в методах доменных сущностей
4. Repositories Pattern
- Интерфейсы: `IAnimalRepository`, `IEnclosureRepository`, `IFeedingScheduleRepository`
- Реализации: InMemory репозитории в `Infrastructure` Layer
- Принцип: Разделение ответственности за доступ к данным
5. Value Objects
- Реализация: DTO классы в Application Layer (`AnimalResponse`, `EnclosureResponse`)
- Назначение: Передача данных между слоями без экспозиции доменных сущностей
6. Bounded Contexts
- Контекст управления животными: `Animal` entity + `AnimalTransferService`
- Контекст управления вольерами: `Enclosure` entity
- Контекст кормления: `FeedingSchedule` entity + `FeedingOrganizationService`
- Контекст статистики: `ZooStatisticsService`
### Принципы SOLID и Clean Code:
Single Responsibility Principle
- Каждый сервис и контроллер имеет одну ответственность
- Репозитории отвечают только за доступ к данным
Dependency Inversion Principle
- Интерфейсы репозиториев в Domain Layer
- Реализации в Infrastructure Layer
- Dependency Injection через конструкторы
Open/Closed Principle
- Легко добавить новые репозитории (например, для БД)
- Возможность расширения функционала через новые сервисы
Interface Segregation Principle
- Каждый репозиторий имеет свой специализированный интерфейс
Тестирование:
Unit Tests (`Tests`)
- Тесты доменных сущностей: `AnimalTests`, `EnclosureTests`, `FeedingScheduleTests`
- Тесты сервисов: `AnimalTransferServiceTests`, `FeedingOrganizationServiceTests`, `ZooStatisticsServiceTests`
### 3. Технологический стек
- `.NET 8.0` - основная платформа
- `ASP.NET Core Web API` - веб-фреймворк
- `Swagger` - документация и тестирование API
- `xUnit` - фреймворк для unit-тестирования
- `FluentAssertions` - библиотека для assertions
- `In-Memory Storage` - временное хранилище данных
### 4. Архитектурные решения
In-Memory репозитории
- Быстрая реализация для демонстрации
- Легко заменить на реальную БД
Separation of Concerns
- Четкое разделение между слоями
- Легкая поддержка и тестирование
Event-Driven Architecture
- Доменные события для отслеживания изменений
- Возможность добавления обработчиков событий
---
## Вывод: Проект успешно реализует все требуемые функции с соблюдением принципов Clean Architecture и Domain-Driven Design.