Anmelden als Dekorateur vs. Abhängigkeitsinjektion - was ist, wenn ich mich in der Klasse anmelden muss?

(Diese Frage habe ich ursprünglich in @ gestelldieser Kommentar, aber Mark Seemann hat mich gebeten, stattdessen eine neue Frage zu erstellen.)

Ich starte eine neue App (ggf. .NET Core) und versuche gerade zu entscheiden, wie genau die Protokollierung erfolgen soll.

Der allgemeine Konsens scheint zu sein, dass die Protokollierung ein Querschnittsthema ist, daher sollte der Protokollierer nicht direkt in die Klasse injiziert werden, die protokollieren soll.

ft gibt es ein Beispiel wie die folgende Klasse, wienich es zu tun

public class BadExample : IExample
{
    private readonly ILogger logger;

    public BadExample(ILogger logger)
    {
        this.logger = logger;
    }

    public void DoStuff()
    {
        try
        {
            // do the important stuff here
        }
        catch (Exception e)
        {
            this.logger.Error(e.ToString());
        }
    }
}

Instead, die Klasse mit der Geschäftslogik sollte nichts über den Logger wissen SRP) und es sollte eine separate Klasse geben, die die Protokollierung durchführt:

public class BetterExample : IExample
{
    public void DoStuff()
    {
        // do the important stuff here
    }
}

public class LoggingBetterExample : IExample
{
    private readonly IExample betterExample;
    private readonly ILogger logger;

    public LoggingBetterExample(IExample betterExample, ILogger logger)
    {
        this.betterExample = betterExample;
        this.logger = logger;
    }

    public void DoStuff()
    {
        try
        {
            this.betterExample.DoStuff();
        }
        catch (Exception e)
        {
            this.logger.Error(e.ToString());
        }
    }
}

Wenn einIExample wird benötigt, der DI-Container gibt eine Instanz von @ zurüLoggingBetterExample, das @ verwendBetterExample (enthält die eigentliche Geschäftslogik) unter der Haube.

Einige Quellen für diesen Ansatz:

Blog-Beiträge vonMark Seemann:

nstrumentierung mit Dekorateuren und AbfangjägeDependency Injection ist lose Kopplung

Blog posten und SO antworten mit Steven:

Mittlerweile ... auf der Kommandoseite meiner ArchitekturWindsor - Transiente Objekte aus dem Container ziehenMeine Frage

ffensichtlich ist dieLoggingBetterExample -Ansatz funktioniert nur, solange die Protokollierung außerhalb der eigentlichen Klasse erfolgen kann.
(wie im obigen Beispiel: fange alle Ausnahmen ab, die von @ geworfen werdBetterExample von außen

Mein Problem ist, dass ich andere Dinge in der aktuellen Klasse protokollieren möchte.
Mark Seemann vermutlich hier dass, wenn jemand dies tun muss, die betreffende Methode möglicherweise auch viel tut.

Wie ich bereits sagte, bin ich in der Planungsphase für eine neue Anwendung, daher muss ich nicht viel Code anzeigen, aber der Anwendungsfall, an den ich gerade denke, sieht ungefähr so aus:

Meine App hat eine Konfigurationsdatei mit einigen optionalen Werten.
Der Benutzer kann die optionalen Werte weglassen, dies ist jedoch eine wichtige Entscheidung.
So möchte ich eine Warnung protokollieren, wenn einige der optionalen Werte fehlen, nur für den Fall, dass dies versehentlich passiert ist.
(Auslassen der Werte ist jedoch völlig in Ordnung, daher kann ich nicht einfach eine Ausnahme auslösen und anhalten)

Das bedeutet, dass ich eine Klasse haben werde, die Konfigurationswerte liest und so etwas tun muss (Pseudocode):

var config = ReadConfigValues("path/to/config.file");

if (config.OptionalValue == null)
{
    logger.Warn("Optional value not set!");
}

Gleichgültig obReadConfigValues ist in dieser oder einer anderen Klasse, ich glaube nicht, dass diese Klasse die SRP verletzen würde.

Wenn ich mich mit einem Dekorateur nicht außerhalb der eigentlichen Klasse anmelden kann, gibt es eine bessere Lösung, als den Logger einzuspritzen?

Ich weiß, dass ich die Konfigurationsdatei in der inneren Klasse lesen kann, aber überprüfe die Werte (und protokolliere die Warnung) im Decorator. Die IMO-Überprüfung des Werts ist jedoch eine Geschäftslogik und keine Infrastruktur. Für mich gehört sie zu derselben Klasse, in der die Konfigurationsdatei gelesen wird.

Antworten auf die Frage(2)

Ihre Antwort auf die Frage