Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.)

like image 812
xvdiff Avatar asked Oct 21 '22 06:10

xvdiff


2 Answers

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.

like image 58
Maarten Avatar answered Oct 24 '22 12:10

Maarten


[...] my domain services don't get access to it

Why not? ILogger should live in the infrastucture layer, but who said that domain layer has no access to infrastructure members?

As far as I know, infrastructure is an unrelated non-domain specific code which solves common problems like I/O, networking, database-access and so on. And logging is an infrastructure concern.

Infrastructure code should implement or provide cross-layer software pieces, and it might provide a infrastructure-based ILogger implementation. If your domain requires some kind of specific code for logging, you'll provide a SomeDomainLogger implemented in the domain layer.

I don't know if you're already using inversion of control, since this is the best way to load such kind of implementations of infrastructure code.

like image 37
Matías Fidemraizer Avatar answered Oct 24 '22 10:10

Matías Fidemraizer