0

I've been studying the Onion Architecture for a couple of weeks now and I've stumbled across a technical dealema.

When I say "module" notice that I'm referring to a notion of project. To be more clear it's compatible to: module = .NET Assembly/Java gradle module

There are 2 module patterns that I have seen so far in most Onion Architecture projects which are:

1 - Each layer possesses its own module so it would have:

  • domain-entities
  • domain-interfaces
  • services-interfaces
  • services
  • infrastructure-data
  • infrastructure-logging
  • ui

2 - All related modules are encapsulated into a single module:

  • core (domain-entities, domain-interfaces, services-interfaces, services)
  • infrastructure (infrastructure-data, infrastructure-logging)
  • ui

The second approach seams pretty much more straightforward to me but I'm not so sure if it will lead to dependency problems in the future. Any advice?

  • 1
    I don't think there is a definitive "right" way. I tend to use something along the lines of your *option 2* until I have a need to split out functionality. In that case those bits start moving towards *option 1*. I find that starting out with *option 1* ends up with too many moving parts. – Eben Roux Mar 15 '18 at 14:07
  • I agree that starting with option 1 is not a good idea for the reasons you mentioned. My fear is that I end up with a bloated core and a bloated infrastructure but as you said I could just split new features/infrastructure concerns if needed. Thanks Eben! – Vinícius M. Freitas Mar 15 '18 at 14:23
  • @ViníciusM.Freitas there could be circular references in solution 1. Also, what kind of *Services* are you referring to? – guillaume31 Mar 19 '18 at 15:24
  • @guillaume31 - I don't think there could be circular references because all dependencies are towards the center, therefore, each layer can only depend on inner layers but not outer layers. The services I'm referring to are Domain Services. Could you elaborate how the first approach could lead to circular reference? – Vinícius M. Freitas Mar 19 '18 at 20:53
  • I thought they were Application Services - do you have any, by the way? Even with separate Domain Services modules, you could have Entity (depends on) Repository interface (depends on) Entity for instance. – guillaume31 Mar 20 '18 at 09:07
  • @guillaume31 - Since this is a backend java application I didn't see the need of an application service yet. My Repositories are build on top of my Entities so there couldn't be references of repositories in my entities because that would break the Onion Architecture philosophy(inner layer cannot depend on outer layers). – Vinícius M. Freitas Mar 20 '18 at 11:23
  • Wait, are you saying that you have yet an additional module for repositories? And even if you don't, onion architecture isn't about putting hard constraints on how objects should reference each other *in the same layer*. – guillaume31 Mar 20 '18 at 12:16

1 Answers1

0

The more modules you have, the less flexible the dependencies between objects because you are constrained by Onion Architecture's strict dependency direction.

Design #1 seems too granular to me. In particular, separating interfaces from implementations prevents you from referencing the interface module from the implementation module, which can be limiting. Sometimes an object in A needs to be loosely coupled to an object in B whose interface is declared in A (DDD repositories come to mind).

guillaume31
  • 13,738
  • 1
  • 32
  • 51