Question

I would like to inject ILog into my classes, not an ILoggerFactoryAdapter, but the ILoggerFactoryAdapter needs the name of the calling class (the class that wants to log something, so i can be properly categorized) so can Autofac somehow identify the class which are requesting the ILog and automaticly create the ILog from the factory?

Was it helpful?

Solution

Bailey Ling came up with a great approach that doesn't use stack walking - see post here: http://groups.google.com/group/autofac/msg/704f926779cbe8b3

OTHER TIPS

I've tried to do this too, but I couldn't find a way to get access to the activation stack of autofac (without patching it) to get to the type that is to be injected with the logger instance.

Below is the "Works On My Machine" certified way (Autofac-1.4.3.536)

protected override void Load(ContainerBuilder builder)
        {
            const string loggerName = "Logger.Name";

            builder.
                Register((c, p) => LogManager.GetLogger(p.Named<string>(loggerName))).
                OnPreparing((c, p) =>
            {
                var stack = p.Context.GetActivationStack();
                var requestingType = "default";
                if (stack != null && stack.Length > 1) requestingType = stack[1].Description;
                var parameters = new List<Parameter>(p.Parameters) { new NamedParameter(loggerName, requestingType) };
                p.Parameters = parameters;

            }).
            FactoryScoped();
}

static class ContextExtensions
{
    public static Autofac.Service[] GetActivationStack(this Autofac.IContext context)
    {
        const string notSupportedMessage = "GetActivationStack not supported for this context.";

        var type = context.GetType();
        if (type.FullName != "Autofac.Context") throw new NotSupportedException(notSupportedMessage);

        var field = type.GetField("_componentResolutionStack", BindingFlags.Instance | BindingFlags.NonPublic);
        if (field == null) throw new NotSupportedException(notSupportedMessage);

        var activationStack = field.GetValue(context) as Stack<Autofac.Service>;
        if (activationStack == null) throw new NotSupportedException(notSupportedMessage);

        return activationStack.ToArray();
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top