Jeroen De Dauw
Jeroen De Dauw

Reputation: 10918

Making contexts explicit in the directory structure

I am looking for feedback on a certain directory structure for an application. I realize that this does not follow the classical stack overflow format where there is such a thing as "a correct answer", though think it is interesting nonetheless. To provide meaningful feedback, some context first needs to be understood, so please bear with me.

--

Two colleagues of mine and I have created an application that uses the Clean Architecture. HTTP requests to routes get turned into request models, which gets handed to use cases, which then spit out a response model that gets handed to a presenter.

The code is fully open source and can be found on GitHub. We also have some docs describing what the main directories are about.

We are thinking about reorganizing our code and would like to get feedback on what we've come up with so far. Primarily amongst the reasons for this reorganization are:

These are the contexts we have identified so far. This is a preliminary list and just to give you an idea, and not the part I want feedback on.

The part I want feedback on is the directory structure we think of switching to:

src/
    Context_1/
        DataAccess/
        Domain/
            Model/
            Repositories/
        UseCases/
        Validation/
        Presentation/
        Authorization/
    Context_2/
    Factories/
    Infrastructure/

tests/
    Context_1/
        Unit/
        Integration/
        EdgeToEdge/
        System/
        TestDoubles/
    Context_2/

The Authorization/ folder directly inside of the context would provide a home for our currently oddly placed authorization code in Infrastructure. Other code not part of our domain, yet binding to it, can go directly into the context folder, and gets its own folder if there is a cohesive/related bunch of stuff amongst it, such as authorization.

I'm happy to provide additional information you need to provide useful feedback.

Upvotes: 3

Views: 389

Answers (1)

tomliversidge
tomliversidge

Reputation: 2369

Right now we do not have a nice place to put things that are not part of our domain, yet somehow bind to it.

Right now these contexts are not explicitly visible in our code, so it is easy to make them dependent on each other, especially when you are not familiar with the domain.

There are both technical and non-technical ways to address this issue:

  • You can enforce stricter separation through class libraries. It is more obvious you are taking a dependency on something if you have to import a dll / reference another project. It will also prevent circular dependencies.
  • Code reviews / discipline is a non-technical way to handle it.

I've been using Hexagonal Architecture with DDD where the domain is in the middle. Other concerns such as repositories are represented by interfaces. Your adapters then take a reference to the domain, but never in the other direction. So you might have an IRepository in your domain, but your WhateverDatabaseRepository sits in it's own project. It is then the responsibility of the application services / command handlers to co-ordinate your use cases and load the adapters. This is also where you would apply cross-cutting concerns such as authorization.

I'd recommend watching Greg Young videos (try this one) and reading Vaughn Vernon's IDDD as it goes into how to structure applications and deals with questions like yours. (sorry that my answer is basically watch a 6hr video and read a 600+ page book, but they both really helped clarify some of the more "wooly" aspects of DDD for me)

As an example, see https://github.com/gregoryyoung/m-r/blob/master/SimpleCQRS/CommandHandlers.cs

Upvotes: 4

Related Questions