A polymorphic association table is a database design pattern that allows a single table to associate with multiple other tables, where the related tables can be of different types.
Scenario: Multiple entities in the domain model have attachments. There is a requirement to have a single attachment table to store attachments of all entity types. Another requirement is to store the attachments in a network folder. This would be recorded in the attachment table with the file path.
I created an entity called Attachment
that corresponds to the polymorphic association table.
public class Attachment
{
public int Id { get; set; }
public string FilePath { get; set; }
public string RelatedEntityName { get; set; }
public int RelatedEntityId { get; set; }
public bool IsDeleted { get; set; }
}
There is an entity called CalendarEvent
that has attachments. RelatedEntityName
would be "CalendarEvent"
for attachments related to CalendarEvent
. By the way, I am not sure if it is correct to have FilePath
inside the domain model. Anyway, I need a way to persist attachments in the data store.
The application has 4 layers.
- Domain
- Application
- Infrastructure
- Presentation
What is the proper way to implement saving attachments for CalendarEvent
as per Domain-Driven Design? My current implementation is as follows.
I have a domain service called CalendarEventAttachmentService
in the Domain layer, that accepts a DTO called AttachmentDto
, which is also in the Domain layer. AttachmentDto
has two properties; FileContent
and FileName
. CalendarEventAttachmentService
has a method that looks like this:
public List<Attachment> CreateAttachments(CalendarEvent calendarEvent, List<AttachmentDto> attachmentDtos, string folderPath)
{
return attachmentDtos.Select(attachment => new Attachment
{
FilePath = folderPath + attachment.FileName,
RelatedEntityName = "CalendarEvent",
RelatedEntityId = calendarEvent.Id,
});
}
In the Application layer, the CreateCalendarEvent
method in the CalendarService
calls the CreateAttachments
method mentioned above, and then adds the returned list of Attachment
to the AttachmentRepository
and saves changes.
This brings me to the topic of aggregate roots. Here, I feel like CalendarService
is an aggregate root but Attachment
is not. I read that only aggregate roots are supposed to have a repository. However, I could not find a way to save attachments to the database without AttachmentRepository
.