1

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 _ids 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?

7
  • whats the essential problem here? dapper cant map to protected fields?
    – Ewan
    Mar 21, 2023 at 10:45
  • 1
    stackoverflow.com/questions/15299946/…
    – Ewan
    Mar 21, 2023 at 10:58
  • @Ewan thanks, I didn't think to check SO first, but both approaches seem pretty hard to maintain, factory because the entity and the record are tightly coupled, and reflection, well, because it's reflection... That said, I think I'm gonna go with the factory approach, thanks! Mar 21, 2023 at 12:05
  • What about having a SetId method with scope "internal"? If your repos are in a different assembly, you can use InternalsVisibleTo to expose SetId to them.
    – Doc Brown
    Mar 21, 2023 at 14:35
  • I’d create an internal constructor to enforce a valid state that includes the Id and expose it with InternalsVisibleTo.
    – Rik D
    Mar 21, 2023 at 17:56

1 Answer 1

1

What I would do is a combination of both approaches(CreateFrom and MapFrom). Let me explain.

but this could potentially allow creating an invalid entity inside the domain

This suggests that your entities are a bit useless. One of the points of DDD is making illegal states irrepresentable. This means that in order to preserve domain invariants your entities should expose constructor of factory method (CreateFrom) and perform all needed validation.

Naturally, this constructor/factory method should not accept your DB entity as a parameter since the domain layer should be the core of your application free from all infrastructure dependencies. This is the reason why on your infrastructure layer you have to have MapFrom method that calls constructor/factory method from of your domain level in order to create always valid domain entity.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.