10

我想将 ILog 注入到我的类中,而不是 ILoggerFactoryAdapter,但是 ILoggerFactoryAdapter 需要调用类的名称(想要记录某些内容的类,所以我可以正确分类)所以 Autofac 可以以某种方式识别正在请求的类ILog 并从工厂自动创建 ILog?

4

2 回答 2

9

Bailey Ling 提出了一种不使用堆栈遍历的好方法 - 请参阅此处的帖子:http ://groups.google.com/group/autofac/msg/704f926779cbe8b3

于 2009-09-05T18:32:42.770 回答
5

我也尝试过这样做,但是我找不到一种方法来访问 autofac 的激活堆栈(无需对其进行修补)以获取要注入记录器实例的类型。

以下是“Works On My Machine”认证方式(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();
    }
}
于 2009-07-22T10:07:22.263 回答