NLog GetCurrentClassLogger() 在使用StructureMap (Full Trust)时出现了NullReferenceException异常。

12

在我的MVC 3应用程序中,尽管在IIS7上以完全信任的环境部署,但似乎NLog无法使用反射来GetCurrentClassLogger()。 我正在使用StructureMap 2.6.1,问题似乎在部署之间偶尔出现。 尽管我不认为StructureMap是原因,但我无法弄清楚为什么。

Bootstrapper类:

public static class Bootstrapper
{
    public static void ConfigureStructureMap()
    {
        ObjectFactory.Initialize(Init);
    }

    private static void Init(IInitializationExpression x)
    {
        x.AddRegistry(new DBServiceRegistry());
        x.AddRegistry(new MyRegistry());
    }
}

Registry类:

public class MyRegistry : Registry
{
    public MyRegistry()//HttpContext context)
    {
        For<ILogger>().Use<NLogLogger>();
        For<IUserRepository>().Use<SqlUserRepository>();
    }
}

我的电脑上一切都很好,但是我部署时为什么会出现System.NullReferenceException: 对象引用未设置为对象的实例错误?

[NullReferenceException: Object reference not set to an instance of an object.]
   NLog.LogManager.GetCurrentClassLogger() +84
   lambda_method(Closure , IArguments ) +40
   StructureMap.Construction.<>c__DisplayClass2.<CreateBuilder>b__0(IArguments args) +22
   StructureMap.Construction.InstanceBuilder.BuildInstance(IArguments args) +12
   StructureMap.Pipeline.ConstructorInstance.Build(Type pluginType, BuildSession session, IInstanceBuilder builder) +88

[StructureMapException: StructureMap Exception Code:  207
Internal exception while creating Instance '38000383-149d-45c2-a8f3-7442316da725' of PluginType Todo.Data.ILogger.  Check the inner exception for more details.]
   StructureMap.Pipeline.ConstructorInstance.Build(Type pluginType, BuildSession session, IInstanceBuilder builder) +276
   StructureMap.Pipeline.ConstructorInstance.build(Type pluginType, BuildSession session) +41
   StructureMap.Pipeline.SmartInstance_1.build(Type pluginType, BuildSession session) +43
   StructureMap.Pipeline.Instance.createRawObject(Type pluginType, BuildSession session) +45
   StructureMap.Pipeline.Instance.Build(Type pluginType, BuildSession session) +36
   StructureMap.Pipeline.ObjectBuilder.Resolve(Type pluginType, Instance instance, BuildSession session) +103
   StructureMap.BuildSession.CreateInstance(Type pluginType, Instance instance) +49
   StructureMap.<>c__DisplayClass3.<.ctor>b__1() +22
   StructureMap.BuildSession.CreateInstance(Type pluginType) +24
   ...etc...snipped

2
我遇到了同样的问题。除了用NullLogger替换NLog之外,还有其他解决方法吗? - N30
我不知道有没有 @N30。 - Petrus Theron
1个回答

28

事实证明这不是一个信任问题,而是一个IoC(控制反转)问题。感谢NInject解决方案让我朝着正确的方向前进。

解决方案

对于您的日志记录包装器,请使用接受字符串参数的构造函数:

public class NLogLogger : ILogger
{
    private Logger _logger;

    public NLogLogger(string currentClassName)
    {
        _logger = LogManager.GetLogger(currentClassName);
    }
    ...
}

NLog StructureMap配置:

For<ILogger>().Use<NLogLogger>()
    .Ctor<string>("currentClassName")
    .Is(x => x.BuildStack.Root.RequestedType.FullName);

2
也可以这样做:x.For<ILogger>().Use( context => new NLogLogger( context.ParentType ) ); - Randy Burden
我使用了这个解决方案,但是按照https://dev59.com/22035IYBdhLWcg3wErrM#14984336中“日志记录器包装器最佳实践”答案建议的方式使用ILogger包装器,以节省维护自己的ILogger包装器的成本。至少在NLog添加他们自己的接口之前。 - Jon Adams

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接