3

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:

  • Right now we do not have a nice place to put things that are not part of our domain, yet somehow bind to it. For instance authorization code, which knows about donation ids (with authorization not being part of the core domain, while donation ids are).

  • It's nice to group cohesive things together. Our Donation code is cohesive and our Membership Application code is cohesive, while both don't depend on each other. This is closely related to the notion of Bounded Contexts in Domain Driven Design. 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.

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.

  • Donation
  • Membership
  • Form support stuff (validation of email, generation of IBAN, etc)

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.

Jeroen De Dauw
  • 10,321
  • 15
  • 56
  • 79

1 Answers1

4

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

Community
  • 1
  • 1
tomliversidge
  • 2,339
  • 1
  • 15
  • 15
  • Are you saying authorization should not be done in the usecases, but instead be done by whatever you call the stuff the invokes a certain usecase? – Jeroen De Dauw Jun 27 '16 at 11:42
  • 1
    The application services would normally implement a use case. So if your use case was to "make a donation" you'd have an application service (or more likely a command handler) to handle this. Inside of this you can make sure the person is authorized to make the donation. – tomliversidge Jun 27 '16 at 12:42
  • 1
    https://github.com/gregoryyoung/m-r/blob/master/SimpleCQRS/CommandHandlers.cs is an example of a command handler. In here you could also pass into the constructor the thing that does authorization. An even better approach is to use the decorator pattern on the command handler class itself. See this point in the video i referenced [here](https://youtu.be/whCk1Q87_ZI?t=4227) – tomliversidge Jun 27 '16 at 12:48