I don't have actual project diagram I can share, but the ideas are fairly straight-forward and will scale.
One way to understand Clean is to re-drawn it using the more conventional layers (see below). Each of the black bounding boxes represents a layer. I've also called out dependencies separately. I have depicted the Entities and Use Cases as one layer - obviously you can separate them if you wish.
The "flow of control" diagram (in the Clean diagram) is basically saying that Layers can consume downwards e.g. technical components like the UI can consume application logic (not the other way around), and that application logic can consume externals like databases (not the other way around). The critical caveat being that you should use loose-coupling mechanisms like DI / Inversion of Control as appropriate (i.e. the "Interfaces Adaptors Layer" in Clean).
Update: one important correction - the connectors show "consumption" (before I incorrectly had them labeled as "dependency").
- E.g. your UI will typically 'consume' the domain layer / app logic, and might do so by calling it directly, which doesn't violate Clean's Dependency Rule; diagramically this is "down the layers".
- Data access code is consumed by the app logic - in this diagram that's also "down the layers" but in the Clean context it's going in the reverse direction, so that consumption needs to be abstracted out so that the Dependency Rule isn't violated.
The other architectural style you can employ ideas from is Vertical Slice. Regardless, you just need to follow the classic high-cohesion / low-coupling principles.
You can then think about the potential packaging, deployment and tiering:
- components in different layers are candidates for separate packaging.
- components in different slices are candidates for separate packaging.
These options are not mutually exclusive, you can combine them in different ways - some of which may be dictated by the technology being used to implement a part of the architecture.
In this second diagram I have coloured the layers to show which of the Clean concepts they map to (Entities / Use cases, Interfaces & Adaptors, etc).
Update: response to comment about Components
Sorry if I was not clear - I was referring to components in a logical sense where "component" simply meant cohesive pieces of code, not a DLL specifically.
Thinking about how you want to logically structure the components of your system ties in with how they can then be packaged and deployed; how they will be reused; how you structure your .Net Projects and how the team(s) actually work on them.
I recall a massive project I worked on in 2010 where I think the project team had ~230 to 250 .Net projects across three solutions, where many projects were in at least 2 of those solutions... the amount of time it took to just open the IDE was poor, let alone compile. The team was not in a position to refactor the codebase at that stage.
Going back to your situation and Clean, taking Cleans "Enterprise Business Logic" as an example... Lets say you identify you have 20 areas/topics of functionality, which translates into 20 areas of logic - you can choose to have 20 namespaces (MyApp.MyLogic.Billing
), put them in 1 project and have them compile into 1 DLL, or you could go the other way and have 20 projects and 20 DLLs.
Or (if it made sense) groupings of several logic areas into the same DLL. Lets say the areas of logic were of different complexity and size (and were correspondingly more likely to change) then you could have the big/complex logic in a single project per area, and smaller trivial ones grouped together AS LONG AS they were reasonably cohesive. E.g. simple finance logic separate from simple product management logic.
When designing the logic structure, project structure and eventual packaging for deployment and use, you'll need to consider a number of aspects (which you probably already are thinking of, but for the sake of a more complete answer), including:
- How to ensure appropriate coupling and cohesion between different parts of the logic, and with the other parts of your system.
- Size and complexity.
- How likely they are to change.
- The degree to which they are, or are likely, to be reused by other parts of the solution.
- How many instances there will be at runtime, in how many different environments (is it one instance in a backend service, or more complicated than that?).
- How easy it will be to modify the code.
- How easy it will be to consume the code e.g. for UI and API developers to build their part of the solution on top of the logic.
- How is the project team(s) likely to be structured; how many developers do you have, etc.
If all else is equal: the more likely it is that something will change (maybe because it is big, complex, is heavily reused, meets real world needs that are volatile, etc) then:
- the more easy it needs to be to facilitate that change (e.g. easy to work on without impacting others, other parts of the code, test, etc)
- and minimize the impacts of the change (e.g. ease of deployment, manage breaking changes, etc).
But that's getting into broader solution considerations such as which system qualities you need to prioritize, which is beyond the scope of this.
Code to Deployment
Based on your question, I spent some time yesterday thinking about how to portrait a Clean based architecture as logical components and then how that could translate into deployment - not what the actual packages were but just where the code needs to end up; from this sort of view you could start identifying actual deployment packages.
This first diagram (below) is basically the same as the first one at the top of my answer: an interpretation of Clean architecture as conventional horizontal layers, showing logical code and components:
This diagram (below) identifies which code is specific to an application and which is common / reused.
This diagram (below) shows where the code is eventually deployed into an application. This is NOT showing specific DLL's and deployment packages, merely where the logical code ends up in terms of which application it is deployed to.