-
Notifications
You must be signed in to change notification settings - Fork 0
Entities
CSF.Entities packages some otherwise-boilerplate logic to describe domain entities (that is, persistent objects mapped to a data-store via an ORM) in a consistent manner. To use this library, your entity classes must implement the interface IEntity
.
If you don't mind using a base class, then you may use Entity<T>
to implement the IEntity
interface. The type parameter T
indicates the type of the identity/primary key value for this entity. Typical choices are long
, int
or Guid
.
The entity base class exposes two protected properties related to the identity; it is up to the developer whether to expose these publicly or not on concrete entity implementations.
Objects derived from IEntity
have an extension method available in the CSF.Entities namespace: GetIdentity()
. This returns an object of type IIdentity<T>
, where the type parameter T
is the type of the entity for which the identity was created.
The identity object is a consistent way to represent the identity of an entity object, without concerning oneself with the underlying data-type of the identity value.
Identities may also be created directly and parsed from other data-types, such a strings.
// In each case, 'id' will be IIdentity<Person>
// Get an identity from an entity instance
var id = aPerson.GetIdentity();
// Create an identity directly
var id = Identity.Create<Person>(5);
// Parse a string as an identity
var id = Identity.Parse<Person>("5");
Neither the entity base class or the IEntity
interface change the default way that equality works for entity classes. To compare entities for identity-equality, use either of:
- An instance of
EntityIdentityEqualityComparer
. - The extension method
IdentityEquals(IEntity)
in the CSF.Entities namespace.
Put simply, entity objects are identity-equal if their identities are equal (see below).
Identities are immutable value objects (not to be confused with value types; they are classes, not structs). As such, their default Equals
method has been overridden.
Two identity objects are equal if their identity values are equal and their entity types are compatible. Two entity types are deemed compatible if either:
- They are the same type
- Both types share a common base type, which:
- Is not
System.Object
- Is not decorated with
[IgnoreForIdentityEquality]
- Is not
Do not use the ==
operator to compare identity instances for equality. For covariance to work, identities are referenced and assigned by the interface IIdentity<T>
and not by their concrete type. This means that operator overloads would not be used, even if they did exist. To avoid confusion, the ==
operator has intentionally not been overloaded for identity types.
To correctly compare identities for equality where either might be null
, use the Object.Equals(object, object)
method.
An attribute is available for entity classes which is useful in two scenarios:
- If you wish to create your own general base class for all entity types
- If your ORM mapping strategy means that 'sibling' classes (subclasses of a common base entity) could coexist with duplicate identity/primary key values
In these cases, those base classes should be decorated with [IgnoreForIdentityEquality]
. This will prevent the identity-equality algorithm from treating entities as equal when they are not.