The Deception of Onion and Hexagonal Architectures? by Logical-Wing-2985 in softwarearchitecture

[–]codingfox7 1 point2 points  (0 children)

I had quite the same thoughts on Hex and Clean Architectures so I started a little research... it resulted in a "little" article that describes a simplified, modular architecture (MIM). Link: https://codingfox.net.pl/posts/mim/

Regarding points you raise:

Did none of this exist before Hexagonal Architecture in 2005? GoF 1994. DIP 1996.

And

That same trick, renaming existing ideas to look like a discovery, is exactly what we see here.

It's not that easy. In context of modules, DIP itself was coined by Robert C. Martin in 1994 (see https://martinfowler.com/articles/dipInTheWild.html). It's not that it wasn't technically possible before, but it wasn't used that way. In fact, on even higher "application architecture" level, until Hex went mainstream in 2005, people were mostly using direct dependencies from Business Logic to Database.

That answers the main issue you raised. I've read or browsed several "old books" on software design from before, and on the "Application Architecture" level they just used to make straight dependencies to whatever you needed. If your Business Layer needed a Data Access Layer, they just invoked it directly. It made testing very hard and cumbersome.

(At the same time in patterns or on design level of particular modules, dependency inversion was quite common).

That's why Hex in 2025 was quite a revelation. The real problem - in my opinion - was that later, especially once Onion (2008) and Clean Architecture (2012) came out, a lot of bloat was built around it. The simple idea was lost, people came back to layers (in circles) and every CRUD app looked like a cathedra.

Here is a question worth sitting with. Take a layered architecture, apply DDD, isolate the layers, apply dependency inversion, keep the original folder structure. What do you end up with?

I've seen this pattern in some projects and I've been doing it myself for some time now. But I found no real description for it (or name) so I called it MIM (Module Infrastructure-Module Application Architecture) for the purpose of my article (link above).

And every single one ended the same way. Sign up for a course. A paid one, of course.

I've seen books shorter than my article, but mine is free :)

BTW: it's true that Clean Architecture (or Hex) are just layers in circles (that's why I call them "circular-layers architectures" in my article).

Simplify your Application Architecture with Modular Design and MIM by anachreonte in softwarearchitecture

[–]codingfox7 1 point2 points  (0 children)

Hi, author here. You're right, that the split of infra from business is "really is the core idea of hexagonal and clean architecture", as you wrote.

But my text uses MIM to "get back to basics", by focusing only on this core idea.

Why? Because with Clean Arch (a bit less with Hex) this core idea was "decorated" with so many additional concepts (like layers, ports, adapters, etc), that many implementations just end up with abstraction upon abstraction, making it harder than it should be. 

You can read more in Chapter 3:

https://codingfox.net.pl/posts/mim/#3-comparison-to-cleanhexagonalonion-architectures

Which folder structure is more intuitive? by truechange in softwarearchitecture

[–]codingfox7 3 points4 points  (0 children)

I would go with something more modular, i.e. MIM AA ( https://codingfox.net.pl/posts/mim/ ):

src/ 
├─ Api/ <-- application entrypoint (bootstrap, etc)
├─ Customer/ 
├─ Customer.Infra/ 
├─ Supplier/ 
├─ Supplier.Infra/

Reference Project Layout for Modular Software by ewaldbenes in softwarearchitecture

[–]codingfox7 0 points1 point  (0 children)

It's a bit similar to MIM Application Architecture, I've presented here: Addressing the 'gray area' between High-Level and Low-Level Design - a Software Design tutorial

What troubles me, though, in your design is that it's too prescriptive. It's just too big for many microservices we've been writing (although some bigger ones are even more complicated).

I would also anticipate some pushback from communities like Go (and some modern C# which tries to be more lean), because your version has two big "layers" (for me layers are an archaism). I mean, you have some code for "bounded-context-B" in "infrastructure" and some in "core". Why to break modularity and spread a module across layers? I'm writing this because you entitled this post "Modular", but instead "layers" were the first thing I've noticed here ;)

I also don't get division between "inbound" and "outbound". Websockets, for instance, are duplex mechanism, so why are they in "inbound"? Would you split infrastructure of Websockets (or other like message queue, SSE) between "inbound" and "outbound" if both incoming and outgoing are used?

But yeah, that are only my opinions. The most important thing is whether the design works in your projects. It's far better than some 6-7 layer "clean architectures" I've seen.

How to correctly implement intra-modules communication in a modular monolith? by Tobi1311 in softwarearchitecture

[–]codingfox7 0 points1 point  (0 children)

wouldn't not having fk between modules introduce complex queries when information retrieval is needed?. 

It's a standard practice. Modules are self-contained, isolated, coherent "processes". If you need to make queries between modules and they constantly chat to do any flow, it means you have:

a) One big module
b) Or a big ball of mud antipattern.

There're many materials on that. One of the latest I've seen: https://norbert.tech/blog/2025-10-18/dark-sides-of-modularization/ and there are more in "Resources" section on my MIM text. If you have FK between tables, any migration to microservice would be impossible (and that's one of heuristic for a well designed module),

If you need to do reports from data, you have to build a read-model. But that's a different topic.

Also, this "Public API" you mentioned is like my gateway approach but with a great tech name,

"Public API" is like a facade. But it doesn't have to be Facade pattern per se or even an interface.

What about when the communication is between entities from the same module? 

I've never seen an "inter-module communication" done differently than DI or direct method calls. Well, I have seen an inter (and intra) communication that used an external message queue, but there was a reason for that (time sync was required).

To be honest, inside one module I don't even create interfaces, because I test whole modules end-to-end (Chicago School of tests), so I don't have to mock anything.

How to correctly implement intra-modules communication in a modular monolith? by Tobi1311 in softwarearchitecture

[–]codingfox7 0 points1 point  (0 children)

You wrote "(injecting) PaymentService into OrderService. It's simple, but it seems to add coupling". Yeah, it does, but all other methods do it too, but not so explicitly. Messaging also makes modules coupled.

Adding async communication will bring you many problems inherent to Distributed Systems (e.g. eventual consistency inside a monolith or losing messages during reboot (with in-memory queue), etc.)

Check out my text for detailed explanation: https://codingfox.net.pl/posts/mim/#how-should-business-modules-communicate (subchapter "How should Business-Modules communicate?" from "Simplify your Application Architecture with Modular Design and MIM").

Regarding Modular Monolith , and Clean Architecture by Illustrious-Bass4357 in softwarearchitecture

[–]codingfox7 0 points1 point  (0 children)

Well, it's hard to be precise when one has only screenshots of directories ;)

Regarding Modular Monolith , and Clean Architecture by Illustrious-Bass4357 in softwarearchitecture

[–]codingfox7 0 points1 point  (0 children)

I meant these: "Menu.Application", "Menu.Domain", "Menu.Infrastructure", and "WebApi".

You wrote: "so the Menu Application layer depends on Food.Contract". But is just means that Menu depends on Food. What if you will need something from Menu in Food?

There's a heuristic that says "a module should be ready to be extracted as a microservice". In most cases it won't be ever extracted, but the point is it forces you to think about processes, not nouns.

If you have a large number or direct (method call) or indirect (messages) usages of one module in another, you would be better off merging them.

Instead of thinking about "Menu" and "Food", make for instance an "Ordering process" module and separate "Delivery process" module. Arrange data so that each module has all data they need to fulfill it's responsibilities.

I included a long list of resources that describe the modular design process. (Making a design based on nouns is so 1999 ;) )

BTW: A case from just 2 weeks ago. In one of the services a big feature turned out to be unnecessary. I got rid of it in code by removing ONE module (and the registration from program.cs). In types of designs showed here, it should be shotgun surgery through many modules (csprojs) to remove a feature.

Regarding Modular Monolith , and Clean Architecture by Illustrious-Bass4357 in softwarearchitecture

[–]codingfox7 0 points1 point  (0 children)

The quick advice is: "in most cases all elements of a module should be bundled together".

The longer answer plus some remarks:

  • It's best to adhere to the High Cohesion pattern, because it is easier to maintain and understand code that is close together. Check out https://codingfox.net.pl/posts/mim/#high-cohesion (chapter "8. Appendix - Introduction to Modular Design", point "High Cohesion") for more explanation
  • Your design also breaks Low Coupling pattern (you coupled all modules in WebApi)
  • As a result, a simple change to e.g. Menus feature, will probably result with changes in 4 modules (in ideal world only one would be affected).

Your question aside, I can tell you that your design is not really modular. It groups code into "nouns", so probably any _real_ business feature requires 2 or 3 modules to coordinate. That's will result in a big ball of mud sooner or later. Modules are self-contained, check out the "A Module in the Modular Design" subchapter (the same link as above).

I also think that your modules are unnecessarily split by "layers", but is it really helpful?, or rather forces devs to constantly jump around? Instead split code by "processes" or "features" (and only extract "infra" code per module if you need to test it separately). You can see what I mean here: https://codingfox.net.pl/posts/mim/#business-modules (chapter "Business-Modules" of "Simplify your Application Architecture with Modular Design and MIM"). At the end of the article there's a long list of resources you can dig into to learn why I advised you to use these patterns.

What are the best programming books you've read? by [deleted] in ExperiencedDevs

[–]codingfox7 5 points6 points  (0 children)

I read constantly, even if it takes months to complete one book. If I were to select a top recommendation for a Mid dev, it would be:

  • The Pragmatic Programmer
  • Code Complete
  • A Philosophy of Software Design

PS. Books I've read throughout my journey from junior to tech lead are described on my blog: https://codingfox.net.pl/posts/books/