سؤال

I have an .NET MVC4 project and I want to wrap NLOG (I have reasons for that) with my Logger and inject it by Castle Windsor. I try something like below. I had no chance to successfully worked it.

public interface ICommonLogger
{
    void Info(string message);

}

public class CommonLogger : ICommonLogger
{
    private readonly Logger _logger;

    public CommonLogger(Type loggerType)
    {
        _logger = LogManager.GetLogger(loggerType.FullName, loggerType); 
    }

    public void Info(string message)
    {
        _logger.Info(message);
    }

}

        container.Register(Component.For<ICommonLogger>().ImplementedBy(typeof(CommonLogger)).LifeStyle.Transient);
        container.Kernel.Resolver.AddSubResolver(new LoggerResolver(container.Kernel));

public class LoggerResolver : ISubDependencyResolver
{
    private readonly IKernel kernel;

    public LoggerResolver(IKernel kernel)
    {
        this.kernel = kernel;
    }

    public bool CanResolve(CreationContext context,
                           ISubDependencyResolver contextHandlerResolver,
                           ComponentModel model,
                           DependencyModel dependency)
    {
        return dependency.TargetType == typeof(ICommonLogger);
    }

    public object Resolve(CreationContext context,
                          ISubDependencyResolver contextHandlerResolver,
                          ComponentModel model,
                          DependencyModel dependency)
    {
        if (CanResolve(context, contextHandlerResolver, model, dependency))
        {
            return kernel.Resolve<ICommonLogger>(new { loggerType = model.Implementation });
        }

        return null;
    }
}

But I am getting the error on enter image description hereimage.

If I use NLOG directly with

container.AddFacility<LoggingFacility>(f => f.UseNLog());

It works with Castle ILogger implementation but I want it to work for own ICommonLogger implemantation.

What I am doing wrong ?

هل كانت مفيدة؟

المحلول

I think you should not be using the LogManager.GetLogger(loggerName, loggerType) overload. That overload is specifically for when you extend NLog by subclassing Logger. In that context, loggerType refers to the type of your subclassed logger. In your case, you are not subclassing Logger. Rather, you are wrapping it.

In your CommonLogger constructor, what object does the Type parameter refer to?

public CommonLogger(Type loggerType)

Is that actually the type of object that Castle is creating for you? That is, does that type correspond to one of your domain objects? As opposed to the actual type of the Logger to create? It seems to to since the error message says that GetLogger is trying to create an instance of LogInController.

Your CommonLogger constructor should probably look something like this:

public CommonLogger(Type typeOfObjectThatWantsALogger)
{
    _logger = LogManager.GetLogger(typeOfObjectThatWantsALogger.FullName); 
}

You might want to go to Castle's repository and look at how they implemented their NLog wrapper and the corresponding Resolver.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top