Search code examples
c#loggingdomain-driven-designonion-architecture

Logging interface in domain layer


I've got some really expensive business logic inside my domain layer where the data must be tracked in order to get a picture of what happened if something fails. Because of this, I want to declare a simple logging interface:

public interface ILogger {
    void Log(LogEntry entry);
}

Now my question is - where does this interface belongs to? Of course logging might be a infrastructure concern (and a little bit of cross layer concern), but if I place it in the infrastructure layer, my domain services don't get access to it. If I place it into the domain layer, I introduce the concept of logging into my domain, which feels awkward.

I'm already using certain concepts from CQRS & EventSourcing inside my application, however throwing a event for like everything that happens with the data inside a domain service seems like an overkill (especially if the data falls into a state that doesn't get returned by a domain service until further transformations have been made.)


Solution

  • There are some options here.

    1. Use decorators. You say you are already using CQRS, so add decorators to the commands/queries which you want to log. The downside is that you can only log before and after the execution of the command/query, not during the execution. And I'm not sure if it will be easy to log for your events as well this way.

    2. Use your interface. If you choose this path, than indeed your ILogger interface should be in the domain layer, because the domain will require a component that implements your logger requirements, so the domain layer is the one to define this interface. The implementation of it must be elsewhere, and in an infrastructure layer sounds fine to me.