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

前端 未结 2 1204
太阳男子
太阳男子 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.

提交回复
热议问题