8

AutoFac を使用するレガシー プロジェクトを更新しており、Simple Logging Facade (SLF) で NLog を使用したい

過去にこれを Ninject で使用したことがありますが、セットアップは非常に簡単です。次のようにするだけです。

kernel.Bind<ILogger>().ToMethod(x => LoggerFactory.GetLogger(x.Request.Target.Member.ReflectedType));

出力は次のようになります。

NLogNinjectSlf.Services.MyService 2013-12-30 15:21:10.5782 注入されたロガーからの DEBUG ログ

簡単なケーキ

しかし、AutoFac を使用する必要があり、ロガーが必要なターゲット タイプを取得する方法がわかりません。

たとえば、次のインターフェイス/クラスがあるとします。

public interface IMyService
{
    void DoSomething();
}

public class MyService : IMyService
{
    private readonly ILogger _logger;

    public MyService(ILogger logger)
    {
        _logger = logger;
    }

    public void DoSomething()
    {
        _logger.Debug("Log from injected Logger");
    }
}

MyServiceクラスのタイプを取得して、ロガーの名前として使用できるようにしたい

AutoFac では、これは私がこれまでに試したことです:

var containerBuilder = new ContainerBuilder();

containerBuilder.RegisterType<MyService>().As<IMyService>();

containerBuilder.Register(x =>
{
    // TODO: Get the correct type
    return LoggerFactory.GetLogger(x.GetType());
}).As<ILogger>();

ところで:私はSLF4Netの背後でNLogを使用していますが、主な問題を解決するために実際には必要ありません...

4

2 に答える 2

10

私を大いに助けてくれたnemesvに感謝します

これは私が最終的に使用したコードです

ところで。必要に応じてプロパティを注入するコードを削除し、すべてのクラスで DI を使用しILoggerてパフォーマンスを向上させるために注入することができます。

public class LoggingModule : Module
{
    protected override void AttachToComponentRegistration(IComponentRegistry componentRegistry,
        IComponentRegistration registration)
    {
        registration.Preparing += OnComponentPreparing;

        registration.Activated += (sender, e) => InjectLoggerProperties(e.Instance);
    }

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

        // Get all the injectable properties to set.
        // If you wanted to ensure the properties were only UNSET properties,
        // here's where you'd do it.
        var properties = instanceType
          .GetProperties(BindingFlags.Public | BindingFlags.Instance)
          .Where(p => p.PropertyType == typeof(ILogger) && p.CanWrite && p.GetIndexParameters().Length == 0);

        // Set the properties located.
        foreach (var propToSet in properties)
        {
            propToSet.SetValue(instance, LoggerFactory.GetLogger(instanceType), null);
        }
    }

    private void OnComponentPreparing(object sender, PreparingEventArgs e)
    {
        var t = e.Component.Activator.LimitType;

        e.Parameters = e.Parameters.Union(
            new[]
            {
                new ResolvedParameter((p, i) => p.ParameterType == typeof (ILogger),
                    (p, i) => LoggerFactory.GetLogger(t))
            });
    }
}

次に、モジュールを登録します。

containerBuilder.RegisterModule<LoggingModule>();
于 2014-01-04T07:25:17.840 に答える