Search code examples
c#.netasp.net-mvcsharp-architecturetypeloadexception

Sporadic "Method 'get_Session' in type from assembly does not have an implementation"


Suddenly the web app that I develop started to give this error message - to the user, but not to me, and only sometimes.

I know that this error can be caused by interface assembly and implementation assembly reference versions mismatch. But I did not update Sharp's version for a long time (still use very old one for this project). Also, the error does not happen always, if it was wrong assemblies I suppose it would always fail.

What can be the reason? Are there any tracing/loggin tools in framework to find out?

Method 'get_Session' in type 'Orders.Data.SafeSessionStorage' 
from assembly 'Orders.Data, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' 
does not have an implementation." 

System.TypeLoadException: Method 'get_Session' in type 'Orders.Data.SafeSessionStorage' from assembly 'Orders.Data, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' does not have an implementation.
   at Orders.Web.MvcApplication.InitializeNHibernateSession()
   at Orders.Web.MvcApplication.<Application_BeginRequest>b__1d()
   at SharpArch.Data.NHibernate.NHibernateInitializer.InitializeNHibernateOnce(Action initMethod)
   at Orders.Web.MvcApplication.Application_BeginRequest(Object sender, EventArgs e)
   at System.Web.HttpApplication.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

Here's the SafeSessionStorage. It is a slightly modified version of SharpArch's one, to support running in background threads.

public class SafeSessionStorage : ISessionStorage
{
  [ThreadStatic]
  private static ISession _session;

  public ISession Session
  {
     get
     {
        HttpContext context = HttpContext.Current;
        if (context == null)
           return _session;
        else
        {
           ISession session = context.Items[factoryKey] as ISession;
           return session;
        }
     }
     set
     {
        HttpContext context = HttpContext.Current;
        if (context == null)
           _session = value;
        else
           context.Items[factoryKey] = value;
     }
  }

  public string FactoryKey
  {
     get { return factoryKey; }
  }

  public static void End()
  {
     if (_session != null)
        _session.Close();
     _session = null;
  }

  public void EndRequest()
  {
     ISession session = Session;

     if (session != null)
     {
        session.Close();
        HttpContext context = HttpContext.Current;
        if (context != null)
           context.Items.Remove(factoryKey);
        else
           _session = null;
     }
  }

  private string factoryKey = NHibernateSession.DefaultFactoryKey;
}

Here's where error happens:

  private void InitializeNHibernateSession()
  {
     NHibernateInitHelper.InitSession(safeSessionStorage,
        Server.MapPath("~/NHibernate.config"),
        Server.MapPath("~/bin/Orders.Data.dll"));
  }

Here InitSession expects ISessionStorage and is passed SafeSessionStorage, so I suppose that's where type checking fails. And I would suspect assemblies versions but, as I said, it always works for me and sometimes works for the user.


Solution

  • I would better accept sehe's comment as answer, but anyway. The problem was a StackOverflowException because of recursive DB data. To debug this I had to add logging to many lines inside the suspected code (the error happened on SOAP service acccess and mapping data using DB), and then analyze. Another approach was to deploy debug build (this is dev server) and use WinDbg, which gave correct exception code 0xe053534f so that I could concentrate on code that may cause this (recursive LINQ method to collect related products).

    The low drive space was a side effect of DW20.exe (dr. watson) eating 1.5 GB space (and CPU).

    Event viewer was a little help because it showed the too generic "kernel32.dll, address 0x0000bee7" error that could be stack overflow and could be anything else.

    Getting "method does not have implementation" is the last information I'd expect from such conditions.