1

このモジュールで NLog を使用しています。

public class LoggingModule : Autofac.Module
{
    protected override void AttachToComponentRegistration(IComponentRegistry componentRegistry, IComponentRegistration registration)
    {
        registration.Preparing += OnComponentPreparing;
        registration.Activated += (sender, e) => InjectLoggerProperties(e.Instance);
    }

    private static void OnComponentPreparing(object sender, PreparingEventArgs e)
    {
        var t = e.Component.Activator.LimitType;
        e.Parameters = e.Parameters.Union(
            new[]
            {
                new ResolvedParameter((p, i) => IsLogger(p), (p, i) => GetLogger(t.FullName))
            });
    }

    private static void InjectLoggerProperties(object instance)
    {
        var instanceType = instance.GetType();

        var properties = instanceType
            .GetProperties(BindingFlags.Public | BindingFlags.Instance)
            .Where(p => IsLogger(p) && p.CanWrite && p.GetIndexParameters().Length == 0);

        foreach (var propToSet in properties)
        {
            propToSet.SetValue(instance, GetLogger(instanceType.FullName), null);
        }
    }

    private static ILogger GetLogger(string name)
    {
        return LogManager.GetLogger(name);
    }

    private static bool IsLogger(ParameterInfo p)
    {
        return p.ParameterType == typeof (ILogger);
    }

    private static bool IsLogger(PropertyInfo p)
    {
        return p.PropertyType == typeof(ILogger);
    }
}

ロガーの名前が空/間違っていることを除いて、すべて正常に動作しているようです。の最初の行でOnComponentPreparing、は期待されるLimitTypeMeta<Lazy<IAutofacActionFilter>>[]代わりに ですLogControllerActionFilterAttribute。ロガーの正しいタイプ名を取得するにはどうすればよいですか? 私のログでは、これはロガー名として与えられています:

0、カルチャ = ニュートラル、PublicKeyToken = b77a5c561934e089]][]

編集:

これは、この問題を示す短い完全なプログラムです。上記のモジュールの実装も必要になります。

internal class Program
{
    private static void Main(string[] args)
    {
        var builder = new ContainerBuilder();
        builder.RegisterModule<LoggingModule>();
        builder.RegisterType<Foo>().As<IFoo>();

        var container = builder.Build();

        // This prints out "0, Culture=neutral, PublicKeyToken=b77a5c561934e089]][]" for the logger name
        foreach (var metalazyfoo in container.Resolve<Meta<Lazy<IFoo>>[]>())
            metalazyfoo.Value.Value.Work(5);

        // This prints out "Foo" for the logger name
        container.Resolve<Meta<Lazy<IFoo>>>().Value.Value.Work(6);

        Console.WriteLine("=== Done ===");
        Console.ReadLine();
    }
}


public class Foo : IFoo
{
    private readonly Logger _logger;

    public Foo(Logger logger)
    {
        _logger = logger;
    }

    public void Work(int x)
    {
        _logger.Debug(x);
    }
}

public interface IFoo
{
    void Work(int x);
}
4

1 に答える 1

1

ここで LimitType は

var t = e.Component.Target.Activator.LimitType;

それ以外の

var t = e.Component.Activator.LimitType;

これは、アクティブ化されている基本コンポーネントのタイプではなく、アクティベーターのタイプでロガーを作成することを避けるためです。これが、LogControllerActionFilterAttribute の代わりに Meta>[] を取得している理由です。

于 2015-05-06T20:20:53.247 に答える