-
Notifications
You must be signed in to change notification settings - Fork 144
Value Objects
Mehdi Hadeli edited this page Apr 26, 2023
·
24 revisions
- Nulls in Value Objects
- Functional C#: Non-nullable reference types
- C# 9 Records as DDD Value Objects with EF Core 6
- Notes about C# records and Nullable Reference Types
- Using Factory method instead of Constuctor
- Using Value Objects with Entity Framework Core
- Implement value objects
- Simple value objects
- Owned Entity Types
- https://github.com/pdevito3/PeakLimsApi/blob/main/PeakLims/src/PeakLims/Domain/Ethnicities/Ethnicity.cs
- https://github.com/pdevito3/PeakLimsApi/blob/main/PeakLims/src/PeakLims/Databases/EntityConfigurations/PatientConfiguration.cs#L37
- https://github.com/pdevito3/TestingServiceRegistration
- https://github.com/AntonioFalcaoJr/Dotnet6.EFCore6.Record.ValueObjects
- https://github.com/kgrzybek/modular-monolith-with-ddd/blob/90ab9b20a1c6e11700e8b357929c5f792b2b32bf/src/Modules/Payments/Domain/Subscriptions/SubscriptionStatus.cs
- https://github.com/kgrzybek/modular-monolith-with-ddd/blob/90ab9b20a1c6e11700e8b357929c5f792b2b32bf/src/Modules/Meetings/Domain/MeetingGroups/MeetingGroupLocation.cs
- Kamil Twitter: If you put validation in ctor and this ctor is used by your infrastructure to instantiate your persisted object then when you change validation you could not be able to load this object. This is why FactoryMethod is better. The second reason is that method has a name, ctor not.
- Note: we should do validation inner factory method instead of constructor
- We could use
ValueConvertion
for simple value objects andOwnOne
for complex value objects, but I usedOwnOne
because with using that we don't need to write conversions. also, with this approach we don't need to call a public constructor explicitly andEF
construct private a constructor for us.
builder.HasIndex(x => x.PhoneNumber).IsUnique();
builder.Property(x => x.PhoneNumber)
.IsRequired(false)
.HasMaxLength(EfConstants.Lenght.Tiny);
.HasConversion(x => (string?)x, x => (PhoneNumber?)x);
builder.OwnsOne(
x => x.PhoneNumber,
a =>
{
a.Property(p => p.Value)
.HasColumnName(nameof(Customer.PhoneNumber).Underscore())
.IsRequired(false)
.HasMaxLength(EfConstants.Lenght.Tiny);
// supporting index on owned types:
// https://github.com/dotnet/efcore/issues/11336
// https://github.com/dotnet/efcore/issues/12637
a.HasIndex(p => p.Value).IsUnique();
});
- Support of unique Index with Owned types properties
- Fluent Api - Mapping an index over more than one column across entity types.
- Note: in entities with none default constructor, for setting constructor parameter, we need a private set property when we didn't define this property in fluent configuration map, because for getting mapping list of properties to set in the constructor it should not be read only without set (for bypassing calculate fields), see more here
- Note: with default constructor in entities, all properties will map from database automatically, see more here
- Ordering with Multiple constructors in the Entity type