.NET Core 6: 10 практических примеров, меняющих подход к разработке

Пройдите тест, узнайте какой профессии подходите
Сколько вам лет
0%
До 18
От 18 до 24
От 25 до 34
От 35 до 44
От 45 до 49
От 50 до 54
Больше 55

Для кого эта статья:

  • Разработчики, работающие с .NET и Microsoft технологиями
  • Специалисты, желающие улучшить свои навыки в веб-разработке и микросервисной архитектуре
  • Слушатели курсов и программы обучения, интересующиеся современными технологиями и инструментами разработки

    .NET Core 6 — настоящий прорыв для экосистемы Microsoft. Эта версия изменила правила игры, предложив минимальные API, горячую перезагрузку и революционные возможности Blazor WebAssembly. Разработчики получили инструменты, сокращающие код на 30-40% без потери функциональности. Любой специалист, серьёзно относящийся к своему профессиональному росту, обязан освоить эти новшества, чтобы оставаться конкурентоспособным. Давайте рассмотрим 10 практических примеров, демонстрирующих мощь .NET Core 6 в реальных проектах. 🚀

Хотите быстро освоить все возможности .NET Core 6 и других современных технологий веб-разработки? Курс Обучение веб-разработке от Skypro — это идеальный старт для профессионального роста. Программа включает не только теорию, но и реальные проекты с .NET Core 6, которые вы добавите в портфолио. Опытные наставники помогут разобраться в тонкостях минимальных API, Blazor и микросервисной архитектуры. Бонуст — трудоустройство в топовые IT-компании после завершения обучения!

Минимальные API в .NET Core 6: создание быстрых эндпоинтов

Минимальные API — одно из важнейших нововведений .NET Core 6, позволяющее создавать облегченные, высокопроизводительные HTTP API с минимальным объемом кода. В отличие от традиционного MVC-подхода, минимальные API идеально подходят для микросервисов и небольших приложений.

Рассмотрим простейший пример создания API с минимальным кодом:

Дмитрий Соколов, технический лид

Когда наша команда начала разрабатывать новую систему мониторинга для крупного логистического сервиса, мы столкнулись с проблемой производительности. Каждые 5 секунд система получала данные от 10000+ устройств. Старая архитектура на .NET 5 MVC не выдерживала нагрузки — CPU постоянно зашкаливал за 90%.

Переход на минимальные API .NET 6 стал спасением. Вот что мы сделали:

csharp
Скопировать код
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

// Эндпоинт для приема телеметрии
app.MapPost("/api/telemetry", async (TelemetryData data, ILogger<Program> logger) => {
try {
await ProcessTelemetryAsync(data);
return Results.Ok();
}
catch (Exception ex) {
logger.LogError(ex, "Ошибка обработки телеметрии");
return Results.Problem("Ошибка обработки данных");
}
});

app.Run();

Результат превзошел ожидания — загрузка CPU снизилась до 35-40%, а пропускная способность выросла на 45%. Устранив overhead контроллеров MVC и сократив количество абстракций, мы получили значительный прирост в скорости без ущерба для функциональности.

Давайте рассмотрим ещё несколько практических примеров использования минимальных API:

1. Создание API для работы с базой данных:

csharp
Скопировать код
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDbContext<TodoDb>(opt => opt.UseInMemoryDatabase("TodoList"));
var app = builder.Build();

// Получение всех Todo-задач
app.MapGet("/todos", async (TodoDb db) =>
await db.Todos.ToListAsync());

// Получение задачи по Id
app.MapGet("/todos/{id}", async (int id, TodoDb db) =>
await db.Todos.FindAsync(id)
is Todo todo
? Results.Ok(todo)
: Results.NotFound());

// Создание новой задачи
app.MapPost("/todos", async (Todo todo, TodoDb db) =>
{
db.Todos.Add(todo);
await db.SaveChangesAsync();
return Results.Created($"/todos/{todo.Id}", todo);
});

// Обновление существующей задачи
app.MapPut("/todos/{id}", async (int id, Todo inputTodo, TodoDb db) =>
{
var todo = await db.Todos.FindAsync(id);
if (todo is null) return Results.NotFound();

todo.Name = inputTodo.Name;
todo.IsComplete = inputTodo.IsComplete;

await db.SaveChangesAsync();
return Results.NoContent();
});

// Удаление задачи
app.MapDelete("/todos/{id}", async (int id, TodoDb db) =>
{
var todo = await db.Todos.FindAsync(id);
if (todo is null) return Results.NotFound();

db.Todos.Remove(todo);
await db.SaveChangesAsync();
return Results.Ok(todo);
});

app.Run();

2. Группировка маршрутов для лучшей организации:

csharp
Скопировать код
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

// Группировка API для управления пользователями
var userApi = app.MapGroup("/api/users");
userApi.MapGet("/", GetAllUsers);
userApi.MapGet("/{id}", GetUserById);
userApi.MapPost("/", CreateUser);
userApi.MapPut("/{id}", UpdateUser);
userApi.MapDelete("/{id}", DeleteUser);

// Группировка API для аутентификации
var authApi = app.MapGroup("/api/auth");
authApi.MapPost("/login", Login);
authApi.MapPost("/register", Register);
authApi.MapPost("/refresh", RefreshToken);

app.Run();

Сравнение минимальных API с традиционным подходом MVC:

Характеристика Минимальные API (.NET 6) MVC API (.NET 5 и ниже)
Объем кода Минимальный (до 70% меньше) Больше (контроллеры, модели, атрибуты)
Производительность Выше (меньше абстракций) Ниже (больше промежуточных слоев)
Время старта Быстрее (до 30%) Медленнее
Подходит для Микросервисы, небольшие API Крупные сложные приложения
Валидация Встроенная + Fluent Validation Атрибуты + DataAnnotations
Пошаговый план для смены профессии

Новые возможности C# 10 для разработчиков .NET Core 6

C# 10, поставляемый с .NET Core 6, предлагает набор мощных функций, упрощающих синтаксис и повышающих продуктивность разработчиков. Давайте рассмотрим наиболее практичные из них.

3. Глобальные директивы using

Глобальные директивы using позволяют объявить пространства имен один раз для всего проекта. Это значительно сокращает шаблонный код в каждом файле.

csharp
Скопировать код
// В файле GlobalUsings.cs или Program.cs
global using System;
global using System.Collections.Generic;
global using System.Linq;
global using System.Threading.Tasks;
global using Microsoft.AspNetCore.Builder;
global using Microsoft.Extensions.DependencyInjection;

// Теперь в остальных файлах проекта эти пространства имен будут доступны
// без явного объявления

4. Файловые пространства имен

Вместо использования блоков с фигурными скобками для пространств имен, C# 10 позволяет использовать более лаконичный синтаксис.

csharp
Скопировать код
// Старый стиль:
namespace MyCompany.MyProject.Services
{
public class MyService
{
// Код сервиса
}
}

// Новый стиль в C# 10:
namespace MyCompany.MyProject.Services;

public class MyService
{
// Код сервиса
}

5. Упрощение создания записей (records)

C# 10 упрощает синтаксис для создания иммутабельных записей с автоматически генерируемыми конструкторами.

csharp
Скопировать код
// В C# 9:
public record Person
{
public string FirstName { get; init; }
public string LastName { get; init; }
}

// В C# 10:
public record Person(string FirstName, string LastName);

// Пример использования:
var developer = new Person("John", "Doe");
// Создание модифицированной копии (без изменения оригинала)
var seniorDeveloper = developer with { LastName = "Smith" };

6. Сокращенная инициализация свойств

C# 10 позволяет устанавливать свойства непосредственно в конструкторе, что значительно упрощает код.

csharp
Скопировать код
// До C# 10:
class UserInfo
{
public string Name { get; set; }
public string Email { get; set; }

public UserInfo(string name, string email)
{
Name = name;
Email = email;
}
}

// С C# 10:
class UserInfo
{
public string Name { get; set; }
public string Email { get; set; }

public UserInfo(string name, string email) => (Name, Email) = (name, email);
}

Основные улучшения C# 10 в контексте разработки на .NET Core 6:

  • Улучшенные лямбда-выражения с автоматическим выводом типов
  • Интерполированные строки в константах для более гибкого определения строковых констант
  • Сопоставление записей для более элегантного pattern matching
  • Расширенная поддержка разделяемых атрибутов для уменьшения дублирования кода
  • Улучшения производительности благодаря оптимизации компилятора

Практическое применение новых возможностей C# 10 в проектах .NET Core 6:

Функция C# 10 Практическое применение Преимущество
Глобальные using Микросервисы с общими зависимостями Сокращение объема кода на 15-20%
Файловые пространства имен Любые .NET Core проекты Улучшение читаемости, меньше вложенности
Records DTO объекты, неизменяемые модели Предотвращение ошибок мутации данных
Константные интерполированные строки API роуты, шаблоны сообщений Более гибкое определение строковых констант
Улучшенные лямбды LINQ запросы, обработчики событий Краткость кода, улучшенная читаемость

Микросервисы на .NET Core 6: пример с Docker-контейнерами

.NET Core 6 предлагает отличные возможности для разработки микросервисов, особенно в сочетании с контейнеризацией Docker. Давайте рассмотрим практический пример создания микросервисной архитектуры. 🐳

7. Разработка микросервиса для обработки заказов

Создадим простой микросервис для обработки заказов с использованием минимальных API и Docker.

csharp
Скопировать код
// OrderService/Program.cs
var builder = WebApplication.CreateBuilder(args);

// Добавляем поддержку БД
builder.Services.AddDbContext<OrderDbContext>(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString("OrdersDb")));

// Добавляем службы
builder.Services.AddScoped<IOrderRepository, OrderRepository>();
builder.Services.AddScoped<IOrderService, OrderProcessingService>();

// Добавляем поддержку MassTransit для сообщений
builder.Services.AddMassTransit(x =>
{
x.UsingRabbitMq((context, cfg) =>
{
cfg.Host(builder.Configuration["RabbitMQ:Host"], "/", h =>
{
h.Username(builder.Configuration["RabbitMQ:Username"]);
h.Password(builder.Configuration["RabbitMQ:Password"]);
});
});
});

var app = builder.Build();

// Создаем API для заказов
app.MapGet("/api/orders", async (IOrderRepository repo) =>
await repo.GetAllOrdersAsync());

app.MapGet("/api/orders/{id}", async (Guid id, IOrderRepository repo) =>
await repo.GetOrderByIdAsync(id) is Order order
? Results.Ok(order)
: Results.NotFound());

app.MapPost("/api/orders", async (OrderRequest orderRequest, 
IOrderService orderService,
IPublishEndpoint publishEndpoint) =>
{
var order = await orderService.CreateOrderAsync(orderRequest);

// Публикуем событие создания заказа
await publishEndpoint.Publish(new OrderCreatedEvent
{
OrderId = order.Id,
CustomerId = order.CustomerId,
Amount = order.TotalAmount,
CreatedAt = DateTime.UtcNow
});

return Results.Created($"/api/orders/{order.Id}", order);
});

app.Run();

Dockerfile для нашего микросервиса:

dockerfile
Скопировать код
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["OrderService/OrderService.csproj", "OrderService/"]
RUN dotnet restore "OrderService/OrderService.csproj"
COPY . .
WORKDIR "/src/OrderService"
RUN dotnet build "OrderService.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "OrderService.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "OrderService.dll"]

8. Создание docker-compose для запуска микросервисной инфраструктуры

yaml
Скопировать код
version: '3.8'

services:
order-service:
image: ${DOCKER_REGISTRY-}order-service
build:
context: .
dockerfile: OrderService/Dockerfile
environment:
- ASPNETCORE_ENVIRONMENT=Development
- ConnectionStrings__OrdersDb=Server=sql-data;Database=OrdersDb;User=sa;Password=Pass@word
- RabbitMQ__Host=rabbitmq
- RabbitMQ__Username=guest
- RabbitMQ__Password=guest
ports:
- "5001:80"
depends_on:
- sql-data
- rabbitmq

notification-service:
image: ${DOCKER_REGISTRY-}notification-service
build:
context: .
dockerfile: NotificationService/Dockerfile
environment:
- ASPNETCORE_ENVIRONMENT=Development
- RabbitMQ__Host=rabbitmq
- RabbitMQ__Username=guest
- RabbitMQ__Password=guest
depends_on:
- rabbitmq

sql-data:
image: mcr.microsoft.com/mssql/server:2019-latest
environment:
- SA_PASSWORD=Pass@word
- ACCEPT_EULA=Y
ports:
- "1433:1433"
volumes:
- sql-data-volume:/var/opt/mssql

rabbitmq:
image: rabbitmq:3-management
ports:
- "15672:15672"
- "5672:5672"
volumes:
- rabbitmq-data:/var/lib/rabbitmq

volumes:
sql-data-volume:
rabbitmq-data:

Преимущества микросервисной архитектуры на .NET Core 6:

  • Независимое масштабирование — каждый сервис можно масштабировать отдельно
  • Технологическая гибкость — возможность использовать разные технологии для разных сервисов
  • Изолированность ошибок — отказ одного сервиса не приводит к падению всей системы
  • Возможность непрерывной поставки — микросервисы можно обновлять независимо
  • Разделение ответственности — каждый сервис фокусируется на конкретной бизнес-возможности

Максим Верховский, архитектор программного обеспечения

Когда мы начали миграцию нашей платформы электронной коммерции с монолита на микросервисы, критическим вопросом стал выбор технологии. Мы остановились на .NET Core 6, и это решение оказалось правильным.

Наш подход заключался в постепенном "вырезании" функциональности из монолита в отдельные микросервисы. Первым стал сервис корзины покупок:

csharp
Скопировать код
// CartService/Program.cs
var builder = WebApplication.CreateBuilder(args);

// Добавляем Redis для хранения корзин
builder.Services.AddStackExchangeRedisCache(options =>
{
options.Configuration = builder.Configuration.GetConnectionString("Redis");
});

// Добавляем сервисы
builder.Services.AddScoped<ICartRepository, RedisCartRepository>();
builder.Services.AddScoped<ICartService, CartService>();

var app = builder.Build();

// API для корзины
app.MapGet("/api/cart/{userId}", async (string userId, ICartRepository repo) =>
await repo.GetCartAsync(userId) is CartModel cart
? Results.Ok(cart)
: Results.NotFound());

app.MapPost("/api/cart/{userId}/items", async (string userId, CartItemDto item, 
ICartService cartService) =>
{
await cartService.AddItemToCartAsync(userId, item);
return Results.Ok();
});

app.Run();

Благодаря новым минимальным API и Docker-поддержке в .NET 6, мы сократили размер кодовой базы на 40% по сравнению с нашим старым монолитом на .NET Framework. Производительность выросла в 3 раза, а время развертывания сократилось с часов до минут.

Главный урок: начинайте с наиболее изолированных компонентов и используйте асинхронную коммуникацию между сервисами где только возможно.

Blazor WebAssembly: интерактивные веб-приложения в .NET Core 6

Blazor WebAssembly — это революционная технология, позволяющая создавать интерактивные клиентские веб-приложения с использованием C# вместо JavaScript. В .NET Core 6 эта технология получила значительные улучшения в производительности и функциональности. 🔥

**

Читайте также

Проверь как ты усвоил материалы статьи
Пройди тест и узнай насколько ты лучше других читателей
Какой фреймворк используется для создания веб-приложений в .NET Core 6?
1 / 5

Загрузка...