14

J'ai une application MVC2 qui est basée sur le Tekpub Starter Site, donc il utilise Ninject pour l'injection de dépendance, NLog pour la journalisation, et un tas d'autres bibliothèques dans divers des endroits. Pour autant que je sache, ce sont eux qui causent mon problème. Tout fonctionne parfaitement sur mon PC en utilisant le serveur de développement ASP.NET (Cassini) mais quand je le déploie sur le serveur (c'est un contrat d'hébergement mutualisé bon marché), j'obtiens une exception NullReferenceException qui semble être liée à l'instanciation de l'enregistreur par Ninject .ASP.NET MVC2 + Ninog + NLog (+ hébergement mutualisé?) = NullReferenceException

est ici les bits correspondants de mes Global.asax.cs

protected override void OnApplicationStarted() { 
    Logger.Info("App is starting"); // <-- I think this is what's causing the problem 

    RegisterRoutes(RouteTable.Routes); 
    //MvcContrib.Routing.RouteDebugger.RewriteRoutesForTesting(RouteTable.Routes); 
    RegisterAllControllersIn(Assembly.GetExecutingAssembly()); 
    SetEngines(); 
} 

protected override IKernel CreateKernel() { 
    return Container; 
} 

internal class SiteModule : NinjectModule { 
    public override void Load() { 
     Bind<ILogger>().To<NLogLogger>(); 
     // and a couple of others... 
    } 
} 

protected void Application_End() { 
    Logger.Info("App is shutting down"); 
} 

protected void Application_Error() { 
    Exception lastException = Server.GetLastError(); 
    Logger.Fatal(lastException); 
} 

public ILogger Logger { 
    get { 
     return Container.Get<ILogger>(); 
     } 
    } 
    static IKernel _container; 
    public static IKernel Container { 
     get { 
      if (_container == null) { 
       _container = new StandardKernel(new SiteModule()); 
      } 
      return _container; 
     } 
    } 

Le 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" > 

    <targets> 
     <!--Useful for debugging--> 
     <target name="console" xsi:type="ColoredConsole" 
     layout="${date:format=HH\:mm\:ss}|${level}|${stacktrace}|${message}" /> 

     <target name="file" xsi:type="File" fileName="${basedir}/App_Data/Site.log" 
     layout="${date}: ${message}" /> 

     <target name="eventlog" xsi:type="EventLog" source="My App" log="Application" 
     layout="${date}: ${message} ${stacktrace}" /> 

    </targets> 

    <rules> 
     <logger name="*" minlevel="Info" writeTo="file" /> 
     <!-- <logger name="*" minlevel="Fatal" writeTo="eventlog" /> --> 
    </rules> 
</nlog> 

La classe NLogLogger:

public class NLogLogger:ILogger { 

    private Logger _logger; 

    public NLogLogger() { 
     _logger = LogManager.GetCurrentClassLogger(); 
    } 

    public void Info(string message) { 
     _logger.Info(message); 
    } 

    // similar for Warn, Debug, etc 

Trace de la pile:

[NullReferenceException: Object reference not set to an instance of an object.] 
    NLog.LogManager.GetCurrentClassLogger() +84 
    DynamicInjector8cdfc2eb02f8497596a4704e379a4bb4(Object[]) +40 
    Ninject.Activation.Providers.StandardProvider.Create(IContext context) +319 
    Ninject.Activation.Context.Resolve() +182 
    Ninject.KernelBase.<Resolve>b__4(IContext context) +8 
    System.Linq.<>c__DisplayClass12`3.<CombineSelectors>b__11(TSource x) +32 
    System.Linq.WhereSelectEnumerableIterator`2.MoveNext() +151 
    System.Linq.<CastIterator>d__b1`1.MoveNext() +92 
    System.Linq.Enumerable.FirstOrDefault(IEnumerable`1 source) +4187840 
    Ninject.ResolutionExtensions.Get(IResolutionRoot root, IParameter[] parameters) +149 
    Web.Application.get_Logger() in C:\mvcstarter\Web\Global.asax.cs:159 
    Web.Application.OnApplicationStarted() in C:\mvcstarter\Web\Global.asax.cs:80 
    Ninject.Web.Mvc.NinjectHttpApplication.Application_Start() +535 

[HttpException (0x80004005): Object reference not set to an instance of an object.] 
    System.Web.HttpApplicationFactory.EnsureAppStartCalledForIntegratedMode(HttpContext context, HttpApplication app) +9024793 
    System.Web.HttpApplication.RegisterEventSubscriptionsWithIIS(IntPtr appContext, HttpContext context, MethodInfo[] handlers) +131 
    System.Web.HttpApplication.InitSpecial(HttpApplicationState state, MethodInfo[] handlers, IntPtr appContext, HttpContext context) +194 
    System.Web.HttpApplicationFactory.GetSpecialApplicationInstance(IntPtr appContext, HttpContext context) +339 
    System.Web.Hosting.PipelineRuntime.InitializeApplication(IntPtr appContext) +253 

[HttpException (0x80004005): Object reference not set to an instance of an object.] 
    System.Web.HttpRuntime.FirstRequestInit(HttpContext context) +8946484 
    System.Web.HttpRuntime.EnsureFirstRequestInit(HttpContext context) +97 
    System.Web.HttpRuntime.ProcessRequestNotificationPrivate(IIS7WorkerRequest wr, HttpContext context) +256 

Si je commente la connexion OnApplicationStarted, j'obtiens une exception différente. Je ne sais pas pourquoi cela se produit, car il ne devrait pas y avoir de journalisation, donc je ne sais pas pourquoi il essaye d'instancier le logger.

[NullReferenceException: Object reference not set to an instance of an object.] 
    NLog.LogManager.GetCurrentClassLogger() +84 
    DynamicInjector5ca7d21cf56b4732957e22cb1bfd8bdd(Object[]) +40 
    Ninject.Activation.Providers.StandardProvider.Create(IContext context) +319 
    Ninject.Activation.Context.Resolve() +182 
    Ninject.KernelBase.<Resolve>b__4(IContext context) +8 
    System.Linq.<>c__DisplayClass12`3.<CombineSelectors>b__11(TSource x) +32 
    System.Linq.WhereSelectEnumerableIterator`2.MoveNext() +151 
    System.Linq.Enumerable.FirstOrDefault(IEnumerable`1 source) +4187840 
    Ninject.Planning.Targets.Target`1.ResolveWithin(IContext parent) +347 
    Ninject.Activation.Providers.StandardProvider.GetValue(IContext context, ITarget target) +138 
    Ninject.Activation.Providers.<>c__DisplayClass2.<Create>b__1(ITarget target) +17 
    System.Linq.WhereSelectArrayIterator`2.MoveNext() +85 
    System.Linq.Buffer`1..ctor(IEnumerable`1 source) +325 
    System.Linq.Enumerable.ToArray(IEnumerable`1 source) +78 
    Ninject.Activation.Providers.StandardProvider.Create(IContext context) +306 
    Ninject.Activation.Context.Resolve() +182 
    Ninject.KernelBase.<Resolve>b__4(IContext context) +8 
    System.Linq.<>c__DisplayClass12`3.<CombineSelectors>b__11(TSource x) +32 
    System.Linq.WhereSelectEnumerableIterator`2.MoveNext() +151 
    System.Linq.<CastIterator>d__b1`1.MoveNext() +92 
    System.Linq.Enumerable.FirstOrDefault(IEnumerable`1 source) +4187840 
    Ninject.ResolutionExtensions.TryGet(IResolutionRoot root, String name, IParameter[] parameters) +261 
    Ninject.Web.Mvc.NinjectControllerFactory.CreateController(RequestContext requestContext, String controllerName) +108 
    System.Web.Mvc.MvcHandler.ProcessRequestInit(HttpContextBase httpContext, IController& controller, IControllerFactory& factory) +124 
    System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state) +50 
    System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, Object state) +48 
    System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) +16 
    System.Web.Mvc.<>c__DisplayClass7.<BeginProcessRequest>b__6() +29 
    System.Web.Mvc.ServerExecuteHttpHandlerWrapper.Wrap(Func`1 func) +38 
    System.Web.Mvc.ServerExecuteHttpHandlerAsyncWrapper.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) +97 
    System.Web.HttpServerUtility.ExecuteInternal(IHttpHandler handler, TextWriter writer, Boolean preserveForm, Boolean setPreviousPage, VirtualPath path, VirtualPath filePath, String physPath, Exception error, String queryStringOverride) +1508 
    System.Web.HttpServerUtility.Execute(IHttpHandler handler, TextWriter writer, Boolean preserveForm, Boolean setPreviousPage) +77 
    System.Web.HttpServerUtility.Execute(IHttpHandler handler, TextWriter writer, Boolean preserveForm) +28 
    System.Web.HttpServerUtilityWrapper.Execute(IHttpHandler handler, TextWriter writer, Boolean preserveForm) +22 
    System.Web.Mvc.Html.ChildActionExtensions.ActionHelper(HtmlHelper htmlHelper, String actionName, String controllerName, RouteValueDictionary routeValues, TextWriter textWriter) +372 
    System.Web.Mvc.Html.ChildActionExtensions.RenderAction(HtmlHelper htmlHelper, String actionName, String controllerName) +35 
    ASP.views_home_index_aspx.__RenderContent2(HtmlTextWriter __w, Control parameterContainer) in c:\HostingSpaces\<snip>\wwwroot\Views\Home\Index.aspx:8 
    System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) +109 
    System.Web.UI.Control.RenderChildren(HtmlTextWriter writer) +8 
    System.Web.UI.Control.Render(HtmlTextWriter writer) +10 
    System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +27 
    System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) +100 
    System.Web.UI.Control.RenderControl(HtmlTextWriter writer) +25 
    ASP.views_shared_site_master.__Render__control1(HtmlTextWriter __w, Control parameterContainer) in c:\HostingSpaces\<snip>\wwwroot\Views\Shared\Site.Master:48 
    System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) +109 
    System.Web.UI.Control.RenderChildren(HtmlTextWriter writer) +8 
    System.Web.UI.Control.Render(HtmlTextWriter writer) +10 
    System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +27 
    System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) +100 
    System.Web.UI.Control.RenderControl(HtmlTextWriter writer) +25 
    System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) +208 
    System.Web.UI.Control.RenderChildren(HtmlTextWriter writer) +8 
    System.Web.Mvc.ViewPage.Render(HtmlTextWriter writer) +55 
    System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +27 
    System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) +100 
    System.Web.UI.Control.RenderControl(HtmlTextWriter writer) +25 
    System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +3060 

La seule façon que je peux obtenir le site de travailler est tout à faux sur l'enregistreur entièrement, que je ne suis pas du tout satisfait. C'est la première fois que je joue avec l'hébergement partagé ASP.NET, donc je suis un peu perdu. Quelqu'un a des suggestions utiles?

+0

La réponse ci-dessous m'a aidé avec un problème quelque peu similaire dans WPF (s'il vous plaît marquer comme la réponse!). Cependant, pour le développement web, il évite des problèmes de débogage bizarre si vous commencez simplement à tester localement sur IIS au lieu de Cassini - tout ce qui rend vos environnements de développement/test/production aussi similaires que possible sauve du chagrin à long terme. – Ted

+0

Tha répondre ci-dessous résout également mon problème: NLog + Ninject ne fonctionne pas sur le mode de libération lorsque le mode de débogage fonctionne bien. – Dariusz

Répondre

34

Vous pouvez éviter d'utiliser LogManager.GetCurrentClassLogger() et laisser Ninject résoudre le nom de la classe actuelle pour vous:

Modifier le constructeur de votre classe NLogLogger dans ce:

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

Et changer le ninject liant pour résoudre le courant classname:

Bind<ILogger>().To<NLogLogger>() 
    .WithConstructorArgument("currentClassName", x => x.Request.ParentContext.Request.Service.FullName); 

Avantage supplémentaire: votre fichier journal inclut désormais le nom de la classe à partir de laquelle la directive log était usé.

Je sais que ma réponse est un peu en retard à la fête, mais je me débattais avec ça moi-même aujourd'hui et je ne pouvais trouver la réponse nulle part. Peut-être que cela aide quelqu'un d'autre.

+0

Votre réponse m'a aidé à trouver une solution StructureMap: http://stackoverflow.com/questions/4519261/nlog-getcurrentclasslogger-nullreferenceexception-using-structuremap-full-trus/4525456#4525456 –

+0

Merci beaucoup Robin, ça était vraiment utile. J'ai perdu presque un jour à me couper les cheveux en essayant de comprendre la cause d'une erreur que je recevais seulement en mode Libération –

+0

Merci. Je recevais également cette erreur uniquement dans la version Release. –

1

Hébergement mutualisé a souvent des restrictions sur la réflexion, etc.

Donc je suppose que

[NullReferenceException:. Référence d'objet non définie à une instance d'un objet] NLog.LogManager.GetCurrentClassLogger () +84

est liée à celle - ce qui se passe si vous obtenez l'enregistreur à l'aide d'un meachanism où vous pase dans un Type que vous obtenez au moment de la compilation via typeof?

+0

L'une des raisons pour lesquelles j'ai choisi l'hôte (en dehors de bas prix - groupe à but non lucratif et tout) est qu'ils n'ont soi-disant aucune restriction sur des choses comme ça. Je ne suis pas non plus un gourou NLog, mais je crois savoir que la méthode que vous avez citée est la façon de l'utiliser, voir http://nlog-project.org/wiki/Tutorial#Creating_loggers par exemple ... I ' J'y jette un coup d'œil quand je rentre à la maison ... – Jon

+0

@Jon: Comme le reste de la planète, j'ai utilisé ma part de bûcherons (et j'en ai honte écrit quelques uns). Je viens d'utiliser log4net et les choses intégrées sur .NET, pas NLog - mais j'ai une connaissance approfondie de la façon dont ça fonctionne avec lo4net et c'est très joli. En regardant l'article cité, ils en ont un où vous passez un nom et un où vous n'avez pas. Celui où vous n'avez pas à déterminer le nom d'une manière ou d'une autre - c'est en quelque sorte la Réflexion. Certaines réflexions (pas toutes) sont restreintes dans l'hébergement partagé. Par conséquent, supprimer 'GetCurrentClassLogger' de l'équation peut éliminer cette cause possible de vos demandes. –

5

Il ressemble NLog ne peut pas fonctionner en fiducie moyen: http://nlog-project.org/forum.html#nabble-td1685352

Si vous regardez dans le global, les journaux d'applications au démarrage ainsi que quand il arrête. Vous devriez être capable d'enlever cela et être heureux.

+0

Ceci a été résolu avec NLog ver. 4.4.1 –

0

J'ai rencontré un problème similaire.

Ma solution (simpliste):

ces lignes remplacent

private Logger Logger = LogManager.GetCurrentClassLogger(); 

par cette ligne

private static Logger Logger = LogManager.GetCurrentClassLogger(); 

Le mot-clé readonly est facultative.