Logging as a decorator vs. Dependency Injection - what if I need to log inside the class?

前端 未结 2 1218
太阳男子
太阳男子 2021-02-12 13:11

(I originally asked this question in this comment, but Mark Seemann asked me to create a new question instead.)

I\'m starting a new app (.NET Core, if that matt

相关标签:
2条回答
  • 2021-02-12 13:53

    checking the value is business logic and not intfastructure, so to me it belongs in the same class where the config file is read.

    Obviously, I don't know your domain well enough to dispute the truth of that assertion, but that logging is part of the domain model sounds strange to me. Anyway, for the sake of argument, let's assume that this is the case.

    What ought not to be the case, though, is that reading a configuration file is domain logic. While reading and manipulating the data from a file could easily be domain logic, reading a file is I/O.

    The most common approach to Inversion of Control in application architecture is to employ the Ports & Adapters architecture. The entire point of such an architecture is to decouple the domain model from I/O, and other sources of non-determinism. The poster example is to show how to decouple the domain model from its database access, but file access falls squarely in that category as well.

    What this ought to imply in this particular case is that you're going to need some IConfigurationReader interface anyway. This means that you can apply a Decorator:

    public class ValidatingConfigurationReader : IConfigurationReader
    {
        private readonly IConfigurationReader reader;
        private readonly ILogger logger;
    
        public ValidatingConfigurationReader(IConfigurationReader reader, ILogger logger)
        {
            this.reader = reader;
            this.logger = logger;
        }
    
        public MyConfiguration ReadConfigValues(string filePath)
        {
            var config = this.reader.ReadConfigValues(filePath);
    
            if (config.OptionalValue == null)
            {
                this.logger.Warn("Optional value not set!");
            }
    
            return config;
        }
    }
    

    This ValidatingConfigurationReader class can be implemented in the domain model, even if the underlying, file-reading IConfigurationReader implementation belongs in some I/O layer.

    0 讨论(0)
  • 2021-02-12 14:10

    Don't take SRP so seriously, otherwise you'll end up with functional programming. If you afraid of getting your class cluttered by putting log statements inside it, then you have two options. The first one you already mentioned which is using a Decorator class but you can't access/log the private stuff. The second option is using partial classes and putting the logging statements in a separate class.

    0 讨论(0)
提交回复
热议问题