title: ASP.NET Core ILoggerProvider for database
body: <p>I am in the middle of studying the ASP.NET Core, and I have implemented logging with a file system successfully, but how about implementing logging feature with a database solution. How to pass EF context to my '<code>LoggerDatabaseProvider</code>', and still have those two decoupled? The code below should clear some upfront questions:</p>
  
  <p>Startup.cs:</p>
  
  <pre><code>    public void ConfigureServices(IServiceCollection services)
      {
          services.AddMvc();
          services.AddEntityFramework()
              .AddEntityFrameworkSqlServer()
              .AddDbContext&lt;WorldContext&gt;();
  
          services.AddTransient&lt;WorldContextSeedData&gt;();
  
  
          services.AddScoped&lt;IWorldRepository, WorldRepository&gt;();
          //this one adds service with Dependency Injection that calls 'MyLogger' constructor with two parameters, instead the default one parametereless constructor. 
          services.AddScoped&lt;ILogger, LoggerFileProvider.Logger&gt;(provider =&gt; new LoggerFileProvider.Logger("CustomErrors", Startup.Configuration["Data:LogFilePath"]));
          //services.AddScoped&lt;ILogger, LoggerDatabaseProvider.Logger&gt;(provider =&gt; new LoggerDatabaseProvider.Logger("CustomErrors"));
      }
  
      public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, WorldContextSeedData seeder)
      {
          string basePath = Startup.Configuration["Data:LogFilePath"];
  
          loggerFactory.AddProvider(new LoggerFileProvider(basePath));
          loggerFactory.AddProvider(new LoggerDatabaseProvider());
  
          app.UseStaticFiles();
  
          app.UseMvc(config =&gt;
          {
              config.MapRoute(
                  name: "Default",
                  template: "{controller}/{action}/{id?}",
                  defaults: new { controller = "App", action = "index" }
                  );
          });
  
          seeder.EnsureSeedData();
      }
  </code></pre>
  
  <p>Here is my successfully implemented logger with text file:</p>
  
  <pre><code>public class LoggerFileProvider : ILoggerProvider
  {
      private readonly string _logFilePath;
  
      public LoggerFileProvider(string logFilePath)
      {
          _logFilePath = logFilePath;
      }
  
      public ILogger CreateLogger(string categoryName)
      {
          return new Logger(categoryName, _logFilePath);
      }
  
      public void Dispose()
      {
      }
  
      public class Logger : ILogger
      {
          private readonly string _categoryName;
          private readonly string _path;
  
          public Logger(string categoryName, string logFilePath)
          {
              _path = logFilePath;
              _categoryName = categoryName;
          }
  
          public bool IsEnabled(LogLevel logLevel)
          {
              return true;
          }
  
          public void Log&lt;TState&gt;(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func&lt;TState, Exception, string&gt; formatter)
          {
              try
              {
                  RecordMsg(logLevel, eventId, state, exception, formatter);
              }
              catch (Exception ex)
              {
                  //this is being used in case of error 'the process cannot access the file because it is being used by another process', could not find a better way to resolve the issue
                  RecordMsg(logLevel, eventId, state, exception, formatter);
              }
          }
  
          private void RecordMsg&lt;TState&gt;(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func&lt;TState, Exception, string&gt; formatter)
          {
              string msg = $"{logLevel} :: {_categoryName} :: {formatter(state, exception)} :: username :: {DateTime.Now}";
  
              using (var writer = File.AppendText(_path))
              {
                  writer.WriteLine(msg);
              }
          }
  
          public IDisposable BeginScope&lt;TState&gt;(TState state)
          {
              return new NoopDisposable();
          }
  
          private class NoopDisposable : IDisposable
          {
              public void Dispose()
              {
              }
          }
      }
  }
  </code></pre>
  
  <p>But how about the very similar implementation, but with database solution? My <code>WorldContext</code> is utilized by EF to communicate with database, but if it would be easier I could utilize my repository. I would like to keep the context/repository decoupled from '<code>LoggerDatabaseProvider</code>' that I am about to implement, so I could utilize it in other projects.</p>