- О проекте
- Архитектура репозитория
- Ключевые возможности
- Технологический стек
- Архитектурные решения и примеры кода
- Демонстрация
- Запуск проекта
- Контакты
OnlineShop - учебный проект, созданный в рамках курса по ASP.NET Core. Он представляет собой полнофункциональный интернет-магазин с корзиной, избранным, сравнением товаров, оформлением заказов, личным кабинетом и админ-панелью. Проект демонстрирует навыки работы с ASP.NET Core MVC, Entity Framework Core, ASP.NET Core Identity, а также реализацию сложной бизнес-логики с помощью паттернов CQRS и MediatR. Кроме того, он интегрируется с отдельным микросервисом отзывов, что показывает понимание микросервисной архитектуры.
Проект построен на многослойной архитектуре с чётким разделением ответственности:
- OnlineShop.Core - модели предметной области, интерфейсы репозиториев, DTO, команды и запросы CQRS.
- OnlineShop.Db - реализация репозиториев, контекст базы данных, миграции, обработчики CQRS (с использованием MediatR).
- OnlineShopWebApp - MVC-приложение, содержащее контроллеры, представления Razor, вспомогательные сервисы (
ReviewsApiService,GuestDataMigrator), хелперы для маппинга и работы с идентификатором пользователя.
Основные архитектурные решения:
- CQRS и MediatR - все операции с товарами (создание, редактирование, удаление, получение) реализованы через команды и запросы, что обеспечивает единую точку входа и упрощает тестирование.
- Репозитории абстрагируют доступ к данным, позволяя легко менять источник (например, перейти с JSON-файлов на БД).
- Кеширование через интерфейс
ICacheService(реализация на Memcached) для часто запрашиваемых данных (список товаров, товар по ID). - Миграция данных гостя сервис
GuestDataMigratorпри входе пользователя переносит его корзину, избранное и сравнение из сессии в постоянную учётную запись. - Интеграция с микросервисом через
HttpClientи сервисReviewsApiServiceс автоматической авторизацией (JWT).
📁 OnlineShop
├── 📁 OnlineShop.Core
│ ├── 📁 Interfaces # ICacheService, IRepository, IReviewsApiService и др.
│ ├── 📁 Models # Сущности (ProductDto, OrderInputModel и др.)
│ └── 📁 Products # Команды/запросы CQRS для товаров
├── 📁 OnlineShop.Db
│ ├── 📁 Handlers # Обработчики CQRS (Products, ...)
│ ├── 📁 Interfaces # Интерфейсы репозиториев (IProductQueryRepository и др.)
│ ├── 📁 Migrations # Миграции EF Core
│ ├── 📁 Models # Сущности БД (Product, Cart, Order, User и др.)
│ ├── 📁 Repositories # Реализации репозиториев
│ └── 📁 Services # MemcachedCacheService
└── 📁 OnlineShopWebApp
├── 📁 Areas
│ ├── 📁 Admin # Контроллеры и представления для администратора
│ └── 📁 UserProfile # Личный кабинет пользователя
├── 📁 Controllers # CartController, ProductController, OrderController и др.
├── 📁 Helpers # MappingExtensions, UserIdHelper, EnumExtensions
├── 📁 Models # ViewModel'и (CartViewModel, OrderViewModel и др.)
├── 📁 Services # ReviewsApiService, TokenService, GuestDataMigrator
├── 📁 Views # Razor-представления
└── 📁 wwwroot # CSS, JS, изображения
- Просмотр списка товаров с пагинацией и поиском.
- Детальная карточка товара с фото и описанием.
- Администрирование товаров (CRUD) через админ-панель.
- Добавление/удаление товаров в корзину, изменение количества.
- Сохранение списков избранного и сравнения для авторизованных и гостевых пользователей.
- Автоматическая миграция данных гостя после входа (
GuestDataMigrator).
Пример кода (репозиторий корзины):
public void AddToCart(int productId, int quantity, string userId)
{
var cart = GetCart(userId);
var existingItem = cart.Items.FirstOrDefault(item => item.ProductId == productId);
if (existingItem != null)
existingItem.Quantity += quantity;
else
cart.Items.Add(new CartItem { ProductId = productId, Quantity = quantity });
_context.SaveChanges();
}- Создание заказа из корзины с валидацией данных покупателя.
- Просмотр истории заказов в личном кабинете.
- Управление статусами заказов для администратора.
- Регистрация и вход с использованием ASP.NET Core Identity.
- Поддержка ролей (администратор, пользователь).
- Личный кабинет с возможностью редактирования профиля и смены пароля.
- Отдельная область
/Adminс управлением товарами, заказами, пользователями и ролями.
- Асинхронное получение отзывов и рейтингов товаров через
ReviewsApiService. - Микросервис
Reviewsзапускается отдельно и предоставляет REST API.
Пример кода (сервис для отзывов):
public async Task<List<Review>> GetReviewsByProductIdAsync(int productId)
{
await AddAuthorizationHeader();
var response = await _httpClient.GetAsync($"/api/Reviews/filter?productId={productId}");
if (response.IsSuccessStatusCode)
return await response.Content.ReadFromJsonAsync<List<Review>>();
return new List<Review>();
}- ASP.NET Core 8 MVC (контроллеры, представления, middleware)
- Entity Framework Core 8 (Code First, миграции)
- SQL Server (LocalDB / Express)
- ASP.NET Core Identity (аутентификация, роли)
- CQRS + MediatR (разделение команд и запросов)
- Кеширование (Memcached через
ICacheService) - FluentValidation (валидация моделей)
- Serilog (логирование в файл и консоль)
- Bootstrap 5, jQuery (фронтенд)
- Git / GitHub
Команды и запросы вынесены в Core, обработчики — в Db. Кеширование прозрачно добавляется в обработчики.
Запрос:
public record GetProductByIdQuery(int Id) : IRequest<ProductDto?>;Обработчик с кешированием:
public class GetProductByIdQueryHandler : IRequestHandler<GetProductByIdQuery, ProductDto?>
{
private readonly IProductQueryRepository _productQueryRepository;
private readonly ICacheService _cache;
public GetProductByIdQueryHandler(IProductQueryRepository productQueryRepository, ICacheService cache)
{
_productQueryRepository = productQueryRepository;
_cache = cache;
}
public async Task<ProductDto?> Handle(GetProductByIdQuery request, CancellationToken cancellationToken)
{
var cacheKey = $"product_{request.Id}";
var cachedProduct = await _cache.GetAsync<ProductDto?>(cacheKey);
if (cachedProduct != null) return cachedProduct;
var product = await _productQueryRepository.GetByIdAsync(request.Id);
if (product == null) return null;
var productDto = product.ToDto();
await _cache.SetAsync(cacheKey, productDto, TimeSpan.FromMinutes(10));
return productDto;
}
}Используется для инкапсуляции логики доступа к данным. Вот фрагмент из CartDbRepository:
public class CartDbRepository : ICartRepository
{
private readonly DatabaseContext _context;
public Cart GetCart(string userId)
{
var cart = _context.Carts
.Include(c => c.Items)
.ThenInclude(i => i.Product)
.FirstOrDefault(c => c.UserId == userId);
if (cart == null)
{
cart = new Cart { UserId = userId };
_context.Carts.Add(cart);
_context.SaveChanges();
}
return cart;
}
}При входе пользователя сервис GuestDataMigrator переносит его корзину, избранное и сравнение из гостевой сессии в постоянный профиль:
public void MigrateGuestData(string userName)
{
MigrateCart(guestId, userName);
MigrateFavorite(guestId, userName);
MigrateComparison(guestId, userName);
}Клиент для HTTP-API микросервиса отзывов с автоматическим добавлением JWT-токена:
public async Task<ProductRatingDto> GetProductRatingAsync(int productId)
{
await AddAuthorizationHeader();
var response = await _httpClient.GetAsync($"/api/Product/{productId}/rating");
if (response.IsSuccessStatusCode)
return await response.Content.ReadFromJsonAsync<ProductRatingDto>();
return new ProductRatingDto { Rating = 0, ReviewCount = 0 };
}| Главная страница каталога | Корзина покупателя | Админ-панель управления |
|---|---|---|
![]() |
![]() |
![]() |
Клонировать репозиторий:
git clone https://github.com/PaulPomogaev/OnlineShop.git
cd OnlineShopНастроить строку подключения к БД в OnlineShopWebApp/appsettings.json:
"ConnectionStrings": {
"online_shop": "Server=.;Database=onlineshop_pomogaev;Integrated Security=true;TrustServerCertificate=true;"
}Применить миграции:
cd OnlineShop.Db
dotnet ef database update --startup-project ../OnlineShopWebApp(Если dotnet ef не установлен: dotnet tool install --global dotnet-ef)
Запустить микросервис отзывов (опционально, но для полной функциональности рекомендуется).
Запустить веб-приложение:
cd ../OnlineShopWebApp
dotnet runОткрыть браузер по адресу https://localhost:5001
- Автор: Paul Pomogaev
- Email: paulslock1@gmail.com
- GitHub: @PaulPomogaev
ASP.NET Core | MVC | Entity Framework Core | CQRS | MediatR | Identity | SQL Server | Корзина | Избранное | Сравнение товаров | Админ-панель | Микросервисы | Clean Architecture | Репозиторий | Кеширование | Memcached | FluentValidation | Serilog | Bootstrap



