Before exploring more alternatives, let’s see how object mapping can help us follow the SOLID principles:

  • S: Using mapper objects helps to separate the responsibility of mapping types from the consumers, making it easier to maintain and refactor the mapping logic.
  • O: By injecting mappers, we can change the mapping logic without changing the code of their consumers.
  • L: N/A
  • I: We explored different designs that provide a small mapper interface that reduces the dependencies between the components.
  • D: The consumers depend only on abstractions, moving the implementation’s binding to the composition root and inverting the dependency flow.

Now that we’ve explored how to extract and use mappers, let’s look at the code smell that emerged.

Code smell – Too many dependencies

Using this kind of mapping could become tedious in the long run, and we would rapidly see scenarios such as injecting three or more mappers into a single request delegate or controller. The consumer would likely already have other dependencies, leading to four or more.That should raise the following flag:

  • Does the class do too much and have too many responsibilities?

In this case, the fine-grained IMapper interface pollutes our request delegates with tons of dependencies on mappers, which is not ideal and makes our code harder to read.

The preferred solution would be to move the exception-handling responsibility away from the delegates or controllers, leveraging a middleware or an exception filter, for example. This tactic would move boilerplate code away from the endpoints.

Since we are talking about mappers, we will explore more object mapping concepts to help us with this problem instead, which applies to many use cases.

As a rule of thumb, you want to limit the number of dependencies to three or less. Over that number, ask yourself if there is a problem with that class; does it have too many responsibilities? Having more than three dependencies is not inherently wrong; it just indicates that you should investigate the design. If nothing is wrong, keep it at 4 or 5, or 10; it does not matter. If you find a way to reduce the number of dependencies or that the class actually does too many things refactor the code.If you don’t like having that many dependencies, you could extract service aggregates that encapsulate two or more dependencies and inject that aggregate instead. Beware that moving your dependencies around does not fix anything; it just moves the problem elsewhere if there was a problem in the first place. Using aggregates could increase the readability of the code, though.

Instead of blindly moving dependencies around, analyze the problem to see if you could create classes with actual logic that could do something useful to reduce the number of dependencies.

Next, let’s have a quick look at aggregating services.