0

I have a web app that uses MEF, Webapi and OData. For MEF I created a helper class that loads the catalog on demand (at first access)

The following is MEF integration code.

Public Shared ReadOnly Property Catalog As AggregateCatalog
    Get
        If _catalog Is Nothing Then

            Dim catFolder = "."
            Dim path = AppDomain.CurrentDomain.BaseDirectory.ToLower
            _catalog = new AggregateCatalog()
            Dim di = New DirectoryInfo(path)
            Dim dlls = di.GetFileSystemInfos("MyApp.*.dll")
            _catalog = New AggregateCatalog()

            For Each dll In dlls
                Try
                    Dim ac = New AssemblyCatalog(Assembly.LoadFile(dll.FullName))
                    Dim parts = ac.Parts.ToArray() 'throws ReflectionTypeLoadException 
                    _catalog.Catalogs.Add(ac)

                Catch ex As ReflectionTypeLoadException
                    Log.Instance.Error("Error when Trying to load {0}", dll.FullName)
                    Log.Instance.Error(ex)
                    For Each iex In ex.LoaderExceptions
                        Log.Instance.Error(iex)
                    Next
                End Try
            Next
        End If
        Return _catalog
    End Get
End Property

One of my projects (the actual web app project) uses the following nuget packages (among others): WebApi 5.2.3 WebApi.OData 5.7.0

My problem is when MEF class tries to load this assembly (the one that uses OData and WebApi, it thrown a runtime error, which is logged below. The problem occurs ONLY in deployment, on production machine. In development all works ok.

As you can see in the error below, it seems that, even if the project references System.Web.Http version 5.2.3.0, at runtime System.Web.Http.Odata assembly is trying to load System.Web.Http version 5.2.2.0 (!?!?!?)

In my project, the reference is set to correct dll (version 5.2.3.0), the dll is set with Copy Local=True, and in web.config I have

  <dependentAssembly>
    <assemblyIdentity name="System.Web.Http" publicKeyToken="31bf3856ad364e35" culture="neutral" />
    <bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
  </dependentAssembly>

I don't have any class needed to be composed by MEF in this project (assembly), so I could simply exclude it from being load by MEF, but this error is puzzling me, and I would like to find a solution, in case I encounter similar problem in other assemblies.

Here is the error I get

2015-11-04 07:17:02.7758|ERROR|MyPermitNow.Log|Error when Trying to load m:\web\www.mypermitnow.org\web_1\bg-processor\MyPermitNow.Jurisdiction.dll
2015-11-04 07:17:02.7758|ERROR|MyPermitNow.Log|System.Reflection.ReflectionTypeLoadException: Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.
   at System.Reflection.RuntimeModule.GetTypes(RuntimeModule module)
   at System.Reflection.RuntimeModule.GetTypes()
   at System.Reflection.Assembly.GetTypes()
   at System.ComponentModel.Composition.Hosting.AssemblyCatalog.get_InnerCatalog()
   at System.ComponentModel.Composition.Hosting.AssemblyCatalog.GetEnumerator()
   at System.Linq.EnumerableQuery`1.GetEnumerator()
   at System.Linq.EnumerableQuery`1.System.Collections.Generic.IEnumerable<T>.GetEnumerator()
   at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
   at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
   at MyPermitNow.MEFHelper.get_Catalog()
System.Reflection.ReflectionTypeLoadException: Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.
   at System.Reflection.RuntimeModule.GetTypes(RuntimeModule module)
   at System.Reflection.RuntimeModule.GetTypes()
   at System.Reflection.Assembly.GetTypes()
   at System.ComponentModel.Composition.Hosting.AssemblyCatalog.get_InnerCatalog()
   at System.ComponentModel.Composition.Hosting.AssemblyCatalog.GetEnumerator()
   at System.Linq.EnumerableQuery`1.GetEnumerator()
   at System.Linq.EnumerableQuery`1.System.Collections.Generic.IEnumerable<T>.GetEnumerator()
   at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
   at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
   at MyPermitNow.MEFHelper.get_Catalog()
2015-11-04 07:17:02.7758|ERROR|MyPermitNow.Log|System.IO.FileLoadException: Could not load file or assembly 'System.Web.Http, Version=5.2.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
File name: 'System.Web.Http, Version=5.2.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'

=== Pre-bind state information ===
LOG: DisplayName = System.Web.Http, Version=5.2.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
 (Fully-specified)
LOG: Appbase = file:///M:/web/www.mypermitnow.org/web_1/bg-processor/
LOG: Initial PrivatePath = NULL
Calling assembly : System.Web.Http.OData, Version=5.7.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35.
===
LOG: This bind starts in default load context.
LOG: No application configuration file found.
LOG: Using host configuration file: 
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config.
LOG: Post-policy reference: System.Web.Http, Version=5.2.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
LOG: Attempting download of new URL file:///M:/web/www.mypermitnow.org/web_1/bg-processor/System.Web.Http.DLL.
WRN: Comparing the assembly name resulted in the mismatch: Build Number
ERR: Failed to complete setup of assembly (hr = 0x80131040). Probing terminated.
bzamfir
  • 4,698
  • 10
  • 54
  • 89

1 Answers1

0

There could be a lot of things that could cause this. Some things to check:

  • Is there an old version of the DLL on the server having problems? It is possible the CSPROJ now has Private=true for the assembly when it didn't use to, then that library is included in the main applicate/site project. So the new one isn't getting copied, but the old one is sitting there but in a more direct spot so it is loading first.
  • Any app/web.config transforms going on that could be replacing the assembly binding XML?
  • If it's not in the direct application folders, what's in the GAC?
  • Turn on the Fusion assembly loading logging
Jon Adams
  • 24,464
  • 18
  • 82
  • 120