Background
I'm currently working on a project using domain-driven design and Dapper as my ORM. The entities are naturally slightly different than the tables in which they are stored (e.g. _id
is protected
rather than public
, collections are read-only, etc.), and I'm struggling to find a good approach for restoring the entities inside my repositories (e.g. mapping the ID
column value to the _id
field or populating backing collections) without exposing entity methods for those database-specific details.
That is to say, I don't want to end up having a SetId(int id)
method inside my entities just to accommodate restoring their non-public _id
s when queried from the database, but I'm struggling to see where I should put the mapping logic and how I could implement it in a maintainable fashion.
What I've tried
Static CreateFrom
entity method
I considered making a CreateFrom
method on my entities to have access to these non-public members, but this could potentially allow creating an invalid entity inside the domain on top of involving implementation details that aren't relevant to the domain.
MapFrom
extension method inside infrastructure
I then figured I could create an extension method that does the same, but inside the infrastructure layer where I actually have to do the mapping. The problem here is that I would need an instance of an entity to 'populate' it using the extension method, and that's confusing.
Private constructor and forced mapping
I thought that perhaps I could add a private constructor that can be called with a CreateEmpty
extension method inside my infrastructure layer, in order to populate it using MapFrom
, but this would again allow for invalid entity states to be persisted.
Using Entity Framework (Core) is not an option
I know EF is powerful enough to do the mapping for me, but unfortunately I'm currently limited to Dapper. How did people organise their codebases before things like EF or NHibernate existed?
SetId
method with scope "internal"? If your repos are in a different assembly, you can useInternalsVisibleTo
to exposeSetId
to them.