Skip to content

Instantly share code, notes, and snippets.

@vkhorikov
Last active April 4, 2021 10:19
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vkhorikov/61f873671630db5a4e0234f9912c660e to your computer and use it in GitHub Desktop.
Save vkhorikov/61f873671630db5a4e0234f9912c660e to your computer and use it in GitHub Desktop.
Hierarchy of value objects - full code
public class Person : Entity
{
public virtual string Name { get; set; }
private readonly DocumentContainer _document;
public virtual Document Document
{
get => _document.Document;
set => _document.Document = value;
}
}
public abstract class Document : ValueObject
{
}
public class IdentityCard : Document
{
public DateTime IssueDate { get; }
public IdentityCard(DateTime issueDate)
{
IssueDate = issueDate;
}
protected override IEnumerable<object> GetEqualityComponents()
{
yield return IssueDate;
}
}
public class Passport : Document
{
public string SerialNumber { get; }
public Passport(string serialNumber)
{
SerialNumber = serialNumber;
}
protected override IEnumerable<object> GetEqualityComponents()
{
yield return SerialNumber;
}
}
public class DocumentContainer
{
private DocumentType _type;
private DateTime? _issueDate;
private string _serialNumber;
public Document Document
{
get
{
switch (_type)
{
case DocumentType.IdentityCard:
return new IdentityCard(_issueDate.Value);
case DocumentType.Passport:
return new Passport(_serialNumber);
default:
throw new ArgumentOutOfRangeException();
}
}
set
{
switch (value)
{
case IdentityCard identityCard:
_issueDate = identityCard.IssueDate;
_serialNumber = null;
_type = DocumentType.IdentityCard;
break;
case Passport passport:
_issueDate = null;
_serialNumber = passport.SerialNumber;
_type = DocumentType.Passport;
break;
}
}
}
}
public enum DocumentType
{
IdentityCard = 1,
Passport = 2
}
public class PersonMap : ClassMap<Person>
{
public PersonMap()
{
Id(x => x.Id);
Map(x => x.Name);
Component<DocumentContainer>(Reveal.Member<Person>("_document"), y =>
{
y.Map(Reveal.Member<DocumentContainer>("_type"), "DocumentType").CustomType<int>().Access.Field();
y.Map(Reveal.Member<DocumentContainer>("_issueDate"), "DocumentIssueDate").Access.Field().Nullable();
y.Map(Reveal.Member<DocumentContainer>("_serialNumber"), "DocumentSerialNumber").Access.Field().Nullable();
}).Access.Field();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment