2016-10-28 31 views
1

您好我试图使用NLog与Web Api 2应用程序使用Ninject进行依赖项注入。NLog如何绑定到ILogger与Ninject和Ninject.Extensions.Logging

我一直在努力寻找到目前为止如何做到这一点的具体信息我已经安装了NLog & NLog.Configuration的NuGet软件包。到目前为止,我读过的文章表明,这些软件包应该可以正常工作,并为我处理绑定。

我设置了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. kernel.Bind<ILogger>().ToMethod(lm => LogManager.GetLogger("MyLogger"));的结合,其中MyLogger是绑定目标配置的名称

当我做1 & 2我得到

试图创建类型的控制装置“ErrorCheckController”时发生错误的错误。确保控制器有一个无参数的公共构造函数。

第三选项得到一个记录器,但它使用的是NLog.config文件

EDIT没有配置 这里是我的配置文件

<?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> 

EDIT 2 我已将我的获取方法更改为

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默默地失败。我把它关掉了,现在我得到了适当的错误。似乎是与我的

一个问题,我得到的错误

例外:在NLog.Targets设置属性“布局”时出错。DatabaseParameterInfo

内部异常:LayoutRenderer无法找到:“appsetting”

我也不太清楚为什么不能我使用的是相同的语法,在文档中的appsetting

找到

回答

1

的问题结束了,我是试图注入

NLog.ILogger

,而不是

Ninject.Extensions.Logging.ILogger

现在正在工作。

1

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

你得到这个错误的原因是:

  1. 你没有配置控制器明确Ninject
  2. 有一个在你的配置

错误,因为有没有显式注册的控制器,Ninject会尝试为你创建它,但由于配置存在问题,它将返回null(这是由指定的合同)。一旦你明确地注册了所有的控制器(你应该总是在容器中显式注册所有的根类型),Ninject会抛出一个表达性的异常来解释配置错误是什么。明确注册所有的根类型也允许你test your DI configuration

+0

嗨我不知道我跟着你,是不是默认在.Net中创建的无参数构造函数?我也在其他项目中使用Ninject,我从来不必显式配置控制器,但我会研究它。我将配置文件添加到原始问题。谢谢 –

+1

@JeffFinn请使用'Bind ()。AsSelf()'注册你的'ErrorCheckController'。我们将在您尝试此操作后继续进行此讨论:) – Steven

+0

谢谢@Steven我绑定了控制器并重试了以前的步骤。我仍然得到相同的错误 –