Domain-Driven Design - Entities in C#
Before you look at the Entities example in C#, you can see at my post on what Entities are in Domain-Driven Design.
Entity interface in C#
public interface IEntity
{
Guid Id { get; }
}
About this code snippet:
- It have an
Id
property without aset
accessor, so this property could only be populated within the constructor of the class that implements it.
Entity base class in C#
public abstract class Entity : IEntity
{
public Guid Id { get; }
protected Entity() { }
protected Entity(Guid id)
{
this.Id = id;
}
public bool Equals(Entity other)
{
if (other is null) return false;
if (this.GetType() != other.GetType()) return false;
if (ReferenceEquals(this, other)) return true;
return this.Id.Equals(other.Id);
}
public override bool Equals(object obj) => this.Equals(obj as Entity);
public static bool operator ==(Entity a, Entity b) => a.Equals(b);
public static bool operator !=(Entity a, Entity b) => !a.Equals(b);
public override int GetHashCode()
{
return base.GetHashCode();
}
}
About this code snippet:
- It is an
abstract
class: This prevents this class from being instantiated and allows to declare abstract methods. - It have a
public
Id
property without aset
accessor, so this property can only be populated within the constructor. - It have an
Equals
method to verify equality with other entities by checking itsId
property.
Entity example in C#
public sealed class User : Entity
{
public FirstName FirstName { get; private set; }
private User() { }
private User(Guid id, FirstName firstName) : base(id)
{
this.FirstName = firstName;
}
public static User Create(Guid id, FirstName firstName)
{
return new User(id, firstName);
}
public void UpdateFirstName(FirstName firstName)
{
if (this.FirstName.Equals(firstName))
throw new InvalidFirstNameException();
this.FirstName = firstName;
}
}
About this code snippet:
- It is a
sealed
class: Prevent another class from extends from this one. - Their properties are
private set
, so they must be modified inside the same class instance. - No public
constructor
: Other classes cannot create instances of this class, except for nested classes. - To create instances of this Value Object we do not call the constructor directly, but it uses the Static Factory Method pattern instead.
- It have methods to change the value of the entity’s properties.
- If an attempt is made to update a property using the same value, it throws an exception.
Categories
Automation scripting Development tools Front end web development Infrastructure Kubernetes Programming guide Security Software architectureTags
Recent Posts
Restart Kubernetes pods following a schedule using Helm
Restart Kubernetes pods following a schedule using Kubectl
Create an Azure Key Vault with RBAC role assignments using Terraform
Get the download url of the latest GitHub release using Bash
Get the download url of the latest GitHub release using PowerShell