Infrastructure реализует интерфейсы из Domain через Entity Framework Core.
OrderRepository.cs
В папке Repositories:
using Microsoft.EntityFrameworkCore;
using OrderManagement.Domain.Entities;
using OrderManagement.Domain.Interfaces;
using OrderManagement.Infrastructure.Persistence;
namespace OrderManagement.Infrastructure.Repositories;
public class OrderRepository : IOrderRepository
{
private readonly OrderDbContext _context;
public OrderRepository(OrderDbContext context) =>
_context = context;
public async Task<Order?> GetByIdAsync(
Guid id, CancellationToken ct = default)
{
return await _context.Orders
.Include(o => o.Items)
.FirstOrDefaultAsync(o => o.Id == id, ct);
}
public async Task<IReadOnlyList<Order>> GetByCustomerIdAsync(
string customerId, CancellationToken ct = default)
{
return await _context.Orders
.Include(o => o.Items)
.Where(o => o.CustomerId == customerId)
.OrderByDescending(o => o.CreatedAt)
.ToListAsync(ct);
}
public async Task AddAsync(
Order order, CancellationToken ct = default) =>
await _context.Orders.AddAsync(order, ct);
public void Update(Order order) =>
_context.Orders.Update(order);
public void Remove(Order order) =>
_context.Orders.Remove(order);
}
.Include(o => o.Items) -- eager loading, загружает позиции заказа через SQL JOIN. Без Include свойство Items будет пустым. AddAsync помечает объект для INSERT, Update -- для UPDATE. Реальный SQL выполняется при SaveChangesAsync.
DependencyInjection.cs для Infrastructure
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using OrderManagement.Domain.Interfaces;
using OrderManagement.Infrastructure.Persistence;
using OrderManagement.Infrastructure.Repositories;
namespace OrderManagement.Infrastructure;
public static class DependencyInjection
{
public static IServiceCollection AddInfrastructure(
this IServiceCollection services,
IConfiguration configuration)
{
services.AddDbContext<OrderDbContext>(options =>
{
options.UseSqlServer(
configuration.GetConnectionString("OrderDB"),
sql => sql.EnableRetryOnFailure(
5, TimeSpan.FromSeconds(30), null));
});
services.AddScoped<IUnitOfWork>(sp =>
sp.GetRequiredService<OrderDbContext>());
services.AddScoped<IOrderRepository, OrderRepository>();
return services;
}
}
AddScoped -- один экземпляр на HTTP-запрос. sp.GetRequiredService<OrderDbContext>() гарантирует, что IUnitOfWork и DbContext -- один объект.