Geir Sagberg
Geir Sagberg

Reputation: 9821

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.

Upvotes: 0

Views: 905

Answers (1)

Geir Sagberg
Geir Sagberg

Reputation: 9821

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.

Upvotes: 0

Related Questions