如何使用Ninject& Nlog绑定到ILogger。 Ninject.Extensions.Logging

时间:2016-10-28 13:21:35

标签: c# asp.net-web-api2 ninject nlog ninject-extensions

您好我正在尝试将NLog与使用Ninject进行依赖注入的Web Api 2应用程序一起使用。

到目前为止,我一直在努力找到有关如何执行此操作的具体信息。我已经为NLog& amp;安装了NuGet软件包。 NLog.Configuration。到目前为止,我所读到的内容表明,这些包应该正常工作,并为我处理绑定。

我设置了Nlog.config文件,然后安装了Ninject.Extensions.Logging& Ninject.Extensions.NLog4包。

我试图按如下方式使用NLog

public class ErrorCheckController : ApiController
{
    private readonly ILogger _logger;

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

    public IHttpActionResult Get(string version)
    {
        try
        {
            throw new Exception("Manually thrown exception");
        }
        catch (Exception ex)
        {
            _logger.Debug(ex);
        }

        return Ok();
    }
}

在我的NinjectWebCommon中,我尝试了

  1. 无约束
  2. kernel.Bind<ILogger>().To<Logger>();
  3. 绑定
  4. kernel.Bind<ILogger>().ToMethod(lm => LogManager.GetLogger("MyLogger"));绑定,其中MyLogger是目标配置的名称
  5. 当我做1&amp; 2我收到错误

      

    尝试创建&#39; ErrorCheckController&#39;类型的控制器时发生错误。确保控制器具有无参数的公共构造函数。

    第3个选项获取Logger但不使用NLog.config文件配置

    修改 这是我的配置文件

    <?xml version="1.0" encoding="utf-8" ?>
    <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd NLog.xsd"
      autoReload="true"
      throwExceptions="false">
    
      <targets>
        <target xsi:type="Database" name="Ink3DPowderDbLogger" connectionStringName="MyDbContext">
          <commandText>
            INSERT INTO Log.ApiLog (
        Application,
        Logger,
        Logged,
        Level,
        Environment,
        Request,
        Message,
        BaseDir,
        Message,
        CallSite,
        CallSiteLn,
        Exception,
        EventProperties,
        StackTrace,
        ServerName,
        Port,
        Url,
        Https,
        ServerAddress,
        RemoteAddress,
        ) VALUES (
        @Application,
        @Logger,
        @Logged,
        @Level,
        @Environment,
        @Request,
        @BaseDir,
        @Message,
        @CallSite,
        @CallSiteLine,
        @Exception,
        @EventProperties,
        @StackTrace,
        @ServerName,
        @Port,
        @Url,
        @Https,
        @ServerAddress,
        @RemoteAddress,
        );
      </commandText>
    
      <parameter name="@application" layout="${appsetting:name=AppName:default=Unknown}" />
      <parameter name="@logger" layout="${logger}" />
      <parameter name="@logged" layout="${date}" />
      <parameter name="@level" layout="${level}" />
      <parameter name="@environment" layout="${environment}" />
      <parameter name="@request" layout="${asp-request}" />
      <parameter name="@basedir" layout="${basedir}" />
      <parameter name="@message" layout="${message}" />
      <parameter name="@callSite" layout="${callsite}" />
      <parameter name="@callSiteLine" layout="${callsite-linenumber}" />
      <parameter name="@exception" layout="${exception:tostring}" />
      <parameter name="@eventproperties" layout="${eventproperties:tostring}" />
      <parameter name="@stacktrace" layout="${stacktrace:tostring}" />
      <parameter name="@serverName" layout="${aspnet-request:serverVariable=SERVER_NAME}" />
      <parameter name="@port" layout="${aspnet-request:serverVariable=SERVER_PORT}" />
      <parameter name="@url" layout="${aspnet-request:serverVariable=HTTP_URL}" />
      <parameter name="@https" layout="${when:inner=1:when='${aspnet-request:serverVariable=HTTPS}' == 'on'}${when:inner=0:when='${aspnet-request:serverVariable=HTTPS}' != 'on'}" />
      <parameter name="@serverAddress" layout="${aspnet-request:serverVariable=LOCAL_ADDR}" />
      <parameter name="@remoteAddress" layout="${aspnet-request:serverVariable=REMOTE_ADDR}:${aspnet-request:serverVariable=REMOTE_PORT}" />
    
    </target>
    
      </targets>
    
      <rules>
        <logger name="*" minlevel="Info" writeTo="Ink3DPowderDbLogger" />
      </rules>
    </nlog>
    

    编辑2 我已将Get方法更改为

    public IHttpActionResult Get(string version)
        {
            IKernel kernel = new StandardKernel();
            //var resolver = new NinjectDependencyResolver(kernel);
            //var logger = (ILogger) resolver.GetService(typeof(ILogger));
            var logger = kernel.Get<ILogger>();
    
            try
            {
                throw new Exception("Manually thrown exception");
            }
            catch (Exception ex)
            {
                //_logger.Debug(ex);
                logger.Debug(ex);
            }
    
            return Ok();
        }
    

    这给了我一个错误

      

    没有匹配的绑定可用,并且该类型不可自我绑定。

    听起来没什么可以与ILogger结合。

    编辑3

    我回顾了我的配置文件,注意到我告诉NLog无声地失败。我把它关掉了,现在我得到了正确的错误。我的

    似乎有问题

    我收到了错误

      

    例外:设置属性&#39;布局&#39;时出错在NLog.Targets.DatabaseParameterInfo

    上      

    内部异常:无法找到LayoutRenderer:&#39; appsetting&#39;

    我不太清楚为什么无法找到这个,我使用的是与appsetting文档相同的语法

2 个答案:

答案 0 :(得分:1)

  

确保控制器具有无参数的公共构造函数。

您收到此错误的原因是:

  1. 您未在Ninject中明确配置控制器
  2. 您的配置中存在错误
  3. 由于没有显式注册控制器,Ninject会尝试为您创建它,但由于配置中存在问题,它将返回null(由IDependencyResolver合同规定)。

    一旦您明确注册了所有控制器(您应该始终在容器中显式注册所有根类型),Ninject将抛出一个表达异常,解释配置错误是什么。明确注册所有根类型还允许您test your DI configuration

答案 1 :(得分:1)

问题最终是因为我试图注入

  

NLog.ILogger

而不是

  

Ninject.Extensions.Logging.ILogger

现在正在运作。