NHibernate-自定义记录器工厂实施的注册

NHibernate-自定义记录器工厂实施的注册,nhibernate,Nhibernate,我只是想实现一个iLogger工厂,以便只将SQL语句转储到文件中进行调试 我使用以下配置让NHibernate知道我的实现 var configuration = new Configuration(); configuration.SetProperty("nhibernate-logger", "SQLLog.LoggerFactory, SQLLog"); 在实现所有必需的方法之前,我想确保NHibernate正在使用我的自定义实现。 因此,我在LoggerFactor

我只是想实现一个iLogger工厂,以便只将SQL语句转储到文件中进行调试

我使用以下配置让NHibernate知道我的实现

var configuration = new Configuration();
        configuration.SetProperty("nhibernate-logger", "SQLLog.LoggerFactory, SQLLog");
在实现所有必需的方法之前,我想确保NHibernate正在使用我的自定义实现。 因此,我在LoggerFactory的默认构造函数中放置了一个断点,以确保NHibernate正在调用我的自定义实现。 不幸的是,断点从未被击中

有人能帮助我如何为NHibernate配置自定义记录器,以及如何确保NHibernate正在使用我注册的LoggerFactory吗

请注意,我想在代码级别进行配置,但不使用任何*.config文件

注意,在同一解决方案中,我在单独的程序集中有NHibernate实现,在单独的程序集中有SQL logger实现。 但这两个二进制文件都放在一个相同的bin文件夹中,我的主应用程序在这个文件夹中运行

using System;
using NHibernate;

namespace SQLLog
{
public class LoggerFactory:ILoggerFactory
{

    public LoggerFactory()
    {
        var mn = string.Empty;
    }

    public IInternalLogger LoggerFor(string keyName)
    {
        throw new NotImplementedException();
    }

    public IInternalLogger LoggerFor(Type type)
    {
        throw new NotImplementedException();
    }
 }
}

显然你写的代码是正确的。所以应该有一些微妙的缺失点。我检查了NH代码,我可以说如果找不到logger工厂类,或者不可实例化等等,就会出现异常。所以我建议做一个如下的检查清单:

configuration.SetProperty("nhibernate-logger", "NotExistingClass.Logger, NotExistingAsm"); 

并检查是否有异常。如果有,配置将在适当的时间完成,而无法调试的事实是由于正在运行的代码与正在调试的代码之间存在一些不一致。如果没有出现异常,则表示您正在配置为延迟,或者您的配置键有输入错误。

我已检查了nhibernate代码,缺少的是web.config上的以下键(不需要configuration.SetProperty):


下面是使用它的方法(NHibernate.LoggerProvider)

private const string NhibernateLoggerConfKey=“nhibernate记录器”;
私有静态字符串GetNHiberNatelogerClass()
{
var nhibernateLogger=ConfigurationManager.AppSettings.Keys.Cast().FirstOrDefault(k=>NhibernateLoggerConfKey.Equals(k.ToLowerInvariant());
字符串nhibernateLoggerClass=null;
if(string.IsNullOrEmpty(nhibernateLogger))
{
//查找log4net.dll
字符串baseDir=AppDomain.CurrentDomain.BaseDirectory;
字符串relativeSearchPath=AppDomain.CurrentDomain.relativeSearchPath;
字符串binPath=relativeSearchPath==null?baseDir:Path.Combine(baseDir,relativeSearchPath);
字符串log4NetDllPath=binPath==null?“log4net.dll”:Path.Combine(binPath,“log4net.dll”);
if(File.Exists(log4NetDllPath))
{
nhibernateLoggerClass=typeof(Log4NetLoggerFactory).AssemblyQualifiedName;
}
}
其他的
{
nhibernateLogger类=ConfigurationManager.AppSettings[nhibernateLogger];
}
返回NHibernateLogger类;
}

简而言之-目前无法通过编程设置nhibernate记录器。 可以添加键“nhibernate logger”或在应用程序配置(app.config/web.config)中配置log4net,以便从NH登录

前面的答案有代码。简言之,NH所做的是:

  • AppSettings(想想web.config)中是否有一个名为nhibernate logger的键
  • 是-尝试并实例化它指向的类
  • 否-在当前应用程序中搜索log4net.dll并使用log4net进行日志记录(需要standart log4net配置)
  • 如果全部失败-无日志记录

  • 在上启用该功能存在一个问题

    dll SQLLog是否部署在调用程序的同一路径中?您好,Felice,是的,SQLLog与调用程序位于同一路径中。工厂类是公共的吗?试着猜测一下:发布你的代码,可能会有帮助。是的,factory类是一个公共类,并且有一个默认构造函数。Felice,谢谢你的更新。我会按照你的建议检查我的实现,并用我的发现不断更新帖子。
    <add key="nhibernate-logger" value="myNamespace.LoggerFactory, myAssemblyName" />
    
        private const string NhibernateLoggerConfKey = "nhibernate-logger";
    
        private static string GetNhibernateLoggerClass()
        {
            var nhibernateLogger = ConfigurationManager.AppSettings.Keys.Cast<string>().FirstOrDefault(k => NhibernateLoggerConfKey.Equals(k.ToLowerInvariant()));
            string nhibernateLoggerClass = null;
            if (string.IsNullOrEmpty(nhibernateLogger))
            {
                // look for log4net.dll
                string baseDir = AppDomain.CurrentDomain.BaseDirectory;
                string relativeSearchPath = AppDomain.CurrentDomain.RelativeSearchPath;
                string binPath = relativeSearchPath == null ? baseDir : Path.Combine(baseDir, relativeSearchPath);
                string log4NetDllPath = binPath == null ? "log4net.dll" : Path.Combine(binPath, "log4net.dll");
    
                if (File.Exists(log4NetDllPath))
                {
                    nhibernateLoggerClass = typeof (Log4NetLoggerFactory).AssemblyQualifiedName;
                }
            }
            else
            {
                nhibernateLoggerClass = ConfigurationManager.AppSettings[nhibernateLogger];
            }
            return nhibernateLoggerClass;
        }