7

Recentemente ho scoperto il serilog (logging strutturato per .net) e ho visto molti dei suoi vantaggi. ma ho dei problemi con questo. ho 4 progetti, uno è web, uno è infrastruttura e gli altri due sono servizi windows, voglio dichiarare la configurazione di serilog una volta e usarla più volte. e anche io voglio usarlo con l'iniezione dipendenza. Ho cercato sul web da tre giorni, ma non ho trovato nulla di utile, per favore qualcuno mi aiuti.Come usare Serilog con Unity?

ad esempio voglio che questa classe sia la mia classe di registrazione.

public interface IMyLogger 
{ 
    void Information(string message, object[] parameters); 
} 

public class MyLogger : IMyLogger 
{ 
    public MyLogger() 
    { 
    } 
    public void Information(string message, object[] parameters) 
    { 
     Log.Information("LogType : {LogType} - Operation : {Operation}", parameters); 
    } 
} 
public class UserClass 
{ 
private readonly IMyLogger _myLogger; 
public UserClass(IMyLogger myLogger) 
     { 
      _myLogger = myLogger; 
     } 
} 

ora non so dove dovrei mettere questa riga di codice:

Log.Logger = new LoggerConfiguration() 
      .WriteTo.Console() 
      .CreateLogger(); 

tnx in anticipo.

risposta

4

Prima di tutto, nella configurazione di Unity, per ottenere Serilog risolvere correttamente, è necessario utilizzare un InjectionFactory, in questo modo:

 container.RegisterType<ILogger>(new ContainerControlledLifetimeManager(), new InjectionFactory((ctr, type, name) => 
     { 
      ILogger log = new LoggerConfiguration() 
       .WriteTo.Console() //Your serilog config here 
       .CreateLogger(); 

      return log; 
     })); 

Nella mia implementazione non sto astraendo Serilog, ma il codice di cui sopra è l'anello mancante in ogni caso. IMyLogger ha solo bisogno di parametro per iniettare ILogger, e tutto funzionerà da solo.

Questo risolve la parte MVC: è possibile inserire IMyLogger nei controller in MVC.

Che ci porta dove trovare questo nella soluzione. A causa delle tue esigenze relative ai servizi, probabilmente devi avere un progetto Inversion of Control separato (MySolution.InversionOfControl) che contenga i tuoi binding. Quindi, per esempio nel UnityWebActivator.cs del tuo sito web, si può fare qualcosa di simile:

/// <summary>Integrates Unity when the application starts.</summary> 
    public static void Start() 
    { 
     //This is the important part: 
     var container = UnityConfig.GetConfiguredContainer(); //This is a static class in the InversionOfControl project. 

     //This is generic: 
     FilterProviders.Providers.Remove(FilterProviders.Providers.OfType<FilterAttributeFilterProvider>().First()); 
     FilterProviders.Providers.Add(new UnityFilterAttributeFilterProvider(container)); 

     DependencyResolver.SetResolver(new UnityDependencyResolver(container)); 
    } 

fare lo stesso per i propri servizi, e si dovrebbe essere pronti per partire!

+0

Questo funziona bene. Ho notato che il gestore della durata predefinito se nessuno specificato in Unity 4.0.1 è il gestore del tempo di vita transitorio. Il che significa che ogni chiamata per risolvere ILogger sta per eseguire la fabbrica di iniezione e ritentare una nuova istanza. Credo che il logger dovrebbe utilizzare ContainerControllerLifetimeManager invece? – dotnetguy

+0

@dotnetguy Meglio tardi che mai, sto aggiornando questo ora. :) –

+1

Per tutti gli altri: ContainerControllerLifetimeManager fa il miglior lavoro di imitazione del comportamento singoletto a cui è stato destinato Serilog. Gli altri gestori di durata funzionano, ma potrebbe essere leggermente più efficiente rispetto alla creazione di una nuova istanza di Serilog per ciascuna richiesta. –