TGViewer
.NET Разработчик .NET Разработчик @netdeveloperdiary · 6.76K subscribers
Post #2170 2.39K
День 1792. #DDD
Объекты-Значения в .NET. Окончание

Начало

Когда использовать объекты-значения?
Для решения проблемы одержимости примитивами и инкапсуляции инвариантов домена. Инкапсуляция — важный аспект любой модели предметной области. У вас не должно быть возможности создать объект значения в недопустимом состоянии.
Объекты-значения также обеспечивают безопасность типов. Сравните:
public interface IPricingService
{
decimal Calculate(
Apartment apartment,
DateOnly start,
DateOnly end);
}

С реализацией, в которую добавлен объекты-значения:
public interface IPricingService
{
PricingDetails Calculate(
Apartment apartment,
DateRange period);
}

Второй вариант гораздо яснее выражает намерение и снижает вероятность ошибок (например, перепутанных дат).

Однако, если применить инварианты нужно только в нескольких местах кода, лучше обойтись без объектов-значений.

Сохранение объектов-значений с помощью EF Core
Объекты-значения можно сохранять, используя принадлежащие (Owned) и комплексные (Complex) типы EF Core.

Принадлежащие типы можно настроить, вызвав метод OwnsOne при настройке сущности. Это укажет EF сохранять объекты-значений в той же таблице в виде дополнительных столбцов:
public void Configure(
EntityTypeBuilder<Apartment> builder)
{
builder.ToTable("apartments");
builder.OwnsOne(p => p.Address);
builder.OwnsOne(p => p.Price, b =>
{
b.Property(m => m.Currency)
.HasConversion(
curr => curr.Code,
code => Currency.FromCode(code));
});
}

Замечания:
- Принадлежащие типы имеют скрытое значение ключа.
- Нет поддержки необязательных (обнуляемых) принадлежащих типов.
- Поддерживаются принадлежащие коллекции с помощью OwnsMany.
- Разделение таблиц позволяет сохранять принадлежащие типы отдельно.

Комплексные типы
Это новая функция EF, доступная в .NET 8. Они не идентифицируются и не отслеживаются по значению ключа, поэтому лучше подходят для хранения объектов-значений. Комплексные типы должны быть частью типа сущности:
public void Configure(
EntityTypeBuilder<Apartment> builder)
{
builder.ToTable("apartments");
builder.ComplexProperty(p => p.Address);
}

Ограничения для комплексных типов:
- Нет поддержки коллекций.
- Нет поддержки обнуляемых значений.

Итого
Объекты-значения помогают разработать богатую модель предметной области. Вы можете использовать их для решения проблемы одержимости примитивами и инкапсуляции инвариантов предметной области. Объекты-значения могут уменьшить количество ошибок, предотвращая создание недопустимых объектов домена.
Вы можете использовать записи или базовый класс ValueObject для представления объектов-значений. Это должно зависеть от конкретных требований и сложности домена.

Источник: https://www.milanjovanovic.tech/blog/value-objects-in-dotnet-ddd-fundamentals
  • 👍 9
More from @netdeveloperdiary
  1. Oct 8, 2026День 2808. #Карьера 5 Навыков, Которые Помогут Быстрее Стать Сеньором. Начало В ИТ есть се…
  2. Oct 7, 2026День 2807. #ЗаметкиНаПолях Типы Коллекций в .NET, Которые Стоит Попробовать. Окончание Нач…
  3. Oct 6, 2026🦈 Открытое собеседование на Middle C# | 6 октября, 19:00 МСК Приглашаем на открытое собес…
  4. Oct 6, 2026День 2806. #ЗаметкиНаПолях Типы Коллекций в .NET, Которые Стоит Попробовать. Начало Больши…
  5. Oct 5, 2026День 2805. #ЧтоНовенького #NET11 Аргументы в Выражениях Коллекций в C#15 В C#15 реализован…
  6. Oct 4, 2026День 2804. #ВопросыНаСобеседовании Марк Прайс предложил свой набор из 60 вопросов (как тех…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →