Search code examples
c#dependency-injectionlight-inject

Using LightInject, how can I register a generic service with a factory method?


I want to configure a logger that logs to xUnit test output, and should be substituted for all ILogger<T> dependencies. As far as I can tell, the way to solve this is to use a generic service with a factory method.

When using Microsoft.Extensions.DependencyInjection, I can do the following:

services.AddTransient(typeof(ILogger<>), 
  factory => factory.GetRequiredService<LoggerFactory>().CreateLogger("TestLogger"));

How can I achieve the same using LightInject?

EDIT: My example does not work, because the created logger cannot be cast to ILogger<T>. I have instead posted my workaround as a solution below.


Solution

  • Turns out I had to solve my problem in a different way:

    1. I copied over XunitLogger from Microsoft.Extensions.Logging.Testing
    2. I created a generic version:

      public class XunitLogger<T> : XunitLogger, ILogger<T>
      {
          public XunitLogger(ITestOutputHelper output) : base(output, typeof(T).Name, LogLevel.Information)
          {
          }
      }
      
    3. I registered the test output helper and the logger:

      public TestBase(ITestOutputHelper testOutputHelper)
      {
          Container.RegisterInstance(testOutputHelper);
          Container.Register(typeof(ILogger<>), typeof(XunitLogger<>));
      }
      

    The key here was that ILogger<T> must be implemented by a generic class, e.g. XunitLogger<T>. Now the messages are logged to my test output.