Search code examples
architecturedomain-driven-design

In DDD, where's the right or recomendable place to call the logging service?


I am working on a C#/.NET project. In order to respect the DDD architecture, where it could be the right or recomendable place to call the logging service (placed at the infrastructure layer, with database persistence)? I mean, should I call the logger in each component at the time the event occurs or should I propagate the messages(for example through OperationResult struct) upward to the application services layer so that instead it is this layer that calls the logging system? or what other way do you recommend and why? It would be recommendable to trigger an event (linked to the logging system) inside each component every time there is needed to logging something (error, warning or information)?

Thank you!


Solution

  • DDD is not an architecture pattern, it only states that you should model your domain, and that all the model, and only the model, should go in a specific domain unit : package, assembly, namespace, ... DDD can be used with any pattern, such as layered, bus, hexagonal, ... Based on DDD alone, the only answer is that logging code should go anywhere but in the domain unit.

    In a classic layered application architecture, you usually have 4 layers:

    • persistence, allows application to store/restore data across time
    • business, enforces business rules integrity for state changing operations
    • presentation, responsible for communication with clients (DTO, MVC, ...)
    • application, transverse features specific to the application

    Logging usually goes in the application layer, along with authentication or application hosting for instance. Also, some applications use a 3-layered architecture, in which case application and presentation layers are usually merged.

    Also note that there are two interpretations of layered architecture, some say you can only reference neighbor layers ; another one states that you can only reference in a given direction, with layer "hopping" allowed.

    Since application layer features are usually cross cutting concerns, it is normal to be able to access features from that layer from any other layer. I suggest against using events since this feature is usually very slow, you can call the logging service directly. If you really care about separation of concern, have a public interface referable from anywhere and use dependency injection to inject protected implementations.