I have been reading about domain driven design and how to implement it while using code first approach for generating a database. From what I've read and researched there are two opinions around this subject:
Have 1 class that serves both as a domain model and a persistence model
Have 2 different classes, one implementing the domain logic and one used for a code-first approach
Now I know opinion 1) is said to simplify small solutions that do not have many differences between the domain and persistence models but I think it breaks the single responsibility principle and by that introduces a lot of issues when an ORM's conventions interfere with DDD.
What is a surprise to me is there are numerous code examples of how to implement opinion 1). But a haven't found a single example of how to implement opinion 2) and how to map the 2 objects. (Probably there are such examples but I failed to find a C# one)
So I tried to implement an example on my own but I am not sure if that's a good way to do it.
Let's say I have a ticketing system and tickets have expiration date. My domain model will look like this:
/// <summary>
/// Domain Model
/// </summary>
public class TicketEntity
{
public int Id { get; private set; }
public decimal Cost { get; private set; }
public DateTime ExpiryDate { get; private set; }
public TicketEntity(int id, decimal cost, DateTime expiryDate)
{
this.Id = id;
this.Cost = cost;
this.ExpiryDate = expiryDate;
}
public bool IsTicketExpired()
{
if (DateTime.Now > this.ExpiryDate)
{
return true;
}
else
{
return false;
}
}
}
The persistence model using Entity Framework as ORM will look almost the same but as the solution grows this might not be the case
/// <summary>
/// ORM code first Persistence Model
/// </summary>
public class Ticket
{
[Key]
public int Id { get; set; }
public decimal Cost { get; set; }
public DateTime ExpiryDate { get; set; }
}
Everything looking great so far. Now what I am not sure about is which is the best place to get a Ticket
persistence model from the repository and how to map it to the TicketEntity
domain model
I have done this in an application/service layer.
public class ApplicationService
{
private ITicketsRepository ticketsRepository;
public ApplicationService(ITicketsRepository ticketsRepository)
{
this.ticketsRepository = ticketsRepository;
}
public bool IsTicketExpired(int ticketId)
{
Ticket persistanceModel = this.ticketsRepository.GetById(ticketId);
TicketEntity domainModel = new TicketEntity(
persistanceModel.Id,
persistanceModel.Cost,
persistanceModel.ExpiryDate);
return domainModel.IsTicketExpired();
}
}
My questions are:
Are there any reasons opinion 1) would be preferred to opinion 2) other than speeding up development and reusing code.
Are there any issues in my approach of mapping the models? Is there something I missed that would bring up issues when a solution grows?
Id
in the Entity? Aren't Entities distinguished from by their references? Isn't theId
persistence only? What if my persistence, which should be unknown, was based on binary serialization? I wouldn't need anId
at all. – Jaynejaynell