Quantcast

NLog vs. Structuremap

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

NLog vs. Structuremap

Tobi
Structuremap uses lambda expressions to create objectes.
The stack frame that GetCurrentClassLogger() gets, does not have a DeclaringType for the calling method (which is a lambda expression) which leads to a NullReferenceException.

What Structuremap does, basically is:

var constructor = typeof (SampleClass).GetConstructor(new Type[] {});
var ctorCall = Expression.New(constructor);
var lambdaExpression = Expression.Lambda(typeof(Func<SampleClass>), ctorCall);
var compiledExpression = (Func<SampleClass>) lambdaExpression.Compile();
compiledExpression();

To make things worse: It works perfectly fine on unoptimized code, but as soon as the compiler optimization is switched on, a NullReferenceException is triggered.

I couldn't figure out a way to retrieve the correct class name from GetCurrentClassLogger, if the classes ctor is called in the way above.

So I guess I have to work around this by:

- Inject the Logger via StructureMap
- or Make the logger of each class static
- or Do something like "private Logger _logger = LogManager.GetClassLogger<MyClass>();"

Tobias
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: NLog vs. Structuremap

Tobi
making the Logger field static avoids this situation with StructureMap.

But I guess it would still be possible to trigger the NullReferenceException, when creating the class from within a DynamicMethod, so NLog should somehow take care of the DeclaringType being null.

http://nlog.codeplex.com/workitem/6315
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: NLog vs. Structuremap

Jarek Kowalski
Administrator
How are you integrating with StructureMap? Could you send a small repro code (including StructureMap, NLog and your bootstrap code).
NLog Blog
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: NLog vs. Structuremap

Tobi
You don't actually need StructureMap to reproduce this. The following code will cause a NullReferenceException if compiler optimization is enabled:

[TestFixture]
public class MyTest
{
    public class SampleClass
    {
        private readonly Logger _logger = LogManager.GetCurrentClassLogger();

        public void DoSomething()
        {
            _logger.Trace("Something");
        }
    }

    [Test]
    public void SomeTest()
    {
        var constructor = typeof (SampleClass).GetConstructor(new Type[] {});
        var ctorCall = Expression.New(constructor);
        var lambdaExpression = Expression.Lambda(typeof(Func<SampleClass>), ctorCall);
        var compiledExpression = (Func<SampleClass>) lambdaExpression.Compile();
        var sampleClass = compiledExpression();
        sampleClass.DoSomething();
    }
}

Making _logger static solved this for me, but there might be situations, where even then GetCurrentClassLogger might find DeclaringType beeing null (haven't tried this yet, but I guess with some DynamicMethod/IL magic this can be reproduced with a static field as well). At least GetCurrentClassLogger() should rethrow a more meaningful exception ("NLog could not determine calling class type" or something similar) or use the method name instead.
Loading...