Integrazione della libreria di log in oggetto multilivello: cos'è una buona struttura?

2

Sto integrando Serilog nella libreria multilayer esistente che ho creato. La precedente tecnica di registrazione che usavo era semplicemente passare una stringa sugli strati con gli eventi. Mi piacerebbe andarmene da questo.

Mi è stato detto per anni che non dovresti mai esporre i bambini a oggetti a livello dei loro genitori, ma questa è l'unica struttura che ho inventato finora. Qualcuno ha un'altra struttura da suggerire?

semplice esempio della struttura che sto usando.

class Program
{
    static void Main(string[] args)
    {
        ILogger logger = new LoggerConfiguration()
            .WriteTo.Console()
            .CreateLogger();

        A a = new A(logger);
        a.DoStuff();

    }
}

class A
{
    public ILogger logger;
    private B b;

    public A(ILogger logger)
    {
        this.logger = logger;
        b = new B(logger);
    }

    public void DoStuff()
    {
        logger.Information("blah class a");
        b.DoStuff();
    }
}

class B
{
    public ILogger logger;
    private C c;
    public B(ILogger logger)
    {
        this.logger = logger;
        c = new C(logger);
    }

    public void DoStuff()
    {
        logger.Information("blah class b");
        c.DoStuff();
    }
}

class C
{

    public ILogger logger;

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

    public void DoStuff()
    {
        logger.Information("blah class c");

        Thread thread = new Thread(() =>
        {
            for (int i  = 0; i  < 10; i ++)
            {
                logger.Information("In thread {i}", i);
            }

        });

        Thread thread2 = new Thread(() =>
        {
            for (int i = 0; i < 10; i++)
            {
                logger.Information("In thread {i}", i);
            }

        });

        thread.Start();
        thread2.Start();

        thread.Join();
        thread2.Join();
    }
    
posta TheColonel26 24.02.2016 - 03:27
fonte

2 risposte

3

Poiché la registrazione è una preoccupazione pervasiva, è spesso utile utilizzare la percentuale di Log anziché passare ILogger tra i componenti:

class Program
{
    static void Main(string[] args)
    {
        Log.Logger = new LoggerConfiguration()
            .WriteTo.Console()
            .CreateLogger();

        A a = new A();
        a.DoStuff();

        Log.CloseAndFlush();
    }
}

class A
{
    private ILogger logger = Log.ForContext<A>();
    private B b;

    public A()
    {
        b = new B();
    }

    public void DoStuff()
    {
        logger.Information("blah class a");
        b.DoStuff();
    }
}

// etc.

Questo stile rende la più importante struttura specifica per l'applicazione del codice più chiaro, invece di eliminare i costruttori ovunque con argomenti ILogger rumorosi.

L'uso di questo modello consente inoltre di introdurre la registrazione in una classe in profondità nella gerarchia degli oggetti, senza dover apportare modifiche a cascata aggiungendo% argomenti diILogger a ogni costruttore o metodo che ne crea un'istanza.

    
risposta data 24.01.2017 - 02:47
fonte
2

Ogni classe dovrebbe creare la propria istanza di logger e usarla. Il costruttore del logger dovrebbe leggere le impostazioni globali di registrazione che l'applicazione ha impostato, preferibilmente da una cache, quindi l'istanziazione del logger non è un granché.

Vedi Log4Net come esempio (e francamente, usa log4net come sistema di registrazione)

In alternativa, puoi utilizzare un'iniezione dipendente per passare un singolo oggetto di log in ciascuno dei tuoi oggetti.

    
risposta data 24.02.2016 - 11:00
fonte

Leggi altre domande sui tag