MEF - неверная версия сборки
У меня есть веб-приложение, которое использует MEF, Webapi и OData. Для MEF я создал вспомогательный класс, который загружает каталог по требованию (при первом доступе)
Ниже приведен код интеграции MEF.
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
Один из моих проектов (настоящий проект веб-приложения) использует следующие пакеты nuget (среди прочих): WebApi 5.2.3 WebApi.OData 5.7.0
Моя проблема в том, что когда класс MEF пытается загрузить эту сборку (ту, которая использует OData и WebApi, он выдает ошибку времени выполнения, которая регистрируется ниже. Проблема возникает ТОЛЬКО при развертывании на рабочей машине. В разработке все работает нормально.
Как вы можете видеть из приведенной ниже ошибки, кажется, что даже если проект ссылается на System.Web.Http версии 5.2.3.0, во время выполнения сборка System.Web.Http.Odata пытается загрузить System.Web.Http версии 5.2. 2.0 (!?!?!?)
В моем проекте ссылка установлена на правильную DLL (версия 5.2.3.0), DLL установлена с Копировать Local = True, и в web.config у меня есть
<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>
У меня нет никакого класса, который должен быть скомпонован MEF в этом проекте (сборке), поэтому я мог бы просто исключить его из загрузки MEF, но эта ошибка меня озадачивает, и я хотел бы найти решение, на случай, если Я сталкиваюсь с подобной проблемой в других сборках.
Вот ошибка, которую я получаю
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.
1 ответ
Там может быть много вещей, которые могут вызвать это. Некоторые вещи, чтобы проверить:
- Есть ли старая версия DLL на сервере, имеющая проблемы? Возможно, что CSPROJ теперь имеет Private=true для сборки, когда он не использовался, тогда эта библиотека включена в основной проект приложения / сайта. Таким образом, новый не копируется, но старый находится там, но в более прямом месте, поэтому он загружается первым.
- Любые происходящие преобразования app/web.config, которые могли бы заменить сборку, связывающую XML?
- Если это не в папках прямого приложения, что находится в GAC?
- Включите ведение журнала загрузки сборки Fusion