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.