Here is the discussion and example how to inject log4net in Autofac.
In DryIoc we may use strongly-typed Factory Method specification to register log4net.ILog:
namespace DryIoc.Docs;
using DryIoc;
using NUnit.Framework;
using System;
using log4net;
class Log4net_logger_example
{
public class A
{
public ILog Logger { get; }
public A(ILog logger)
{
Logger = logger;
}
}
[Test]
public void Example()
{
var container = new Container();
container.Register<A>();
container.Register(Made.Of<ILog>(() =>
LogManager.GetLogger(Arg.Index<string>(0)),
request => request.Parent.ImplementationType.Name.ToString()));
var a = container.Resolve<A>();
Assert.IsNotNull(a.Logger);
}
}
Made.Of
Arg.Index<Type>(0)
argument references to the value: request => request.Parent.ImplementationType
,
which evaluates to the typeof(A)
in the example.
The code is similar to the log4net with using dependency parent type as context for instantiating of ILogger
.
In addition, the condition allows to use default logger where context is not available, e.g. at resolution root.
class Serilog_logger_example
{
public class LogSubject
{
public Serilog.ILogger Logger { get; }
public LogSubject(Serilog.ILogger logger)
{
Logger = logger;
}
}
[Test]
public void Example()
{
var container = new Container();
// default logger
container.Register(Made.Of(() => Serilog.Log.Logger),
setup: Setup.With(condition: r => r.Parent.ImplementationType == null));
// type dependent logger
container.Register(
Made.Of(() => Serilog.Log.ForContext(Arg.Index<Type>(0)), r => r.Parent.ImplementationType),
setup: Setup.With(condition: r => r.Parent.ImplementationType != null));
var defaultLogger = container.Resolve<Serilog.ILogger>();
Assert.AreSame(Serilog.Log.Logger, defaultLogger);
container.Register<LogSubject>();
var s = container.Resolve<LogSubject>();
Assert.AreSame(Serilog.Log.ForContext<LogSubject>(), s.Logger);
}
}