繁体   English   中英

如何在C#中找到错误的程序集引用

[英]How to Find a Bad Assembly Reference in C#

我很难在C#/ Azure应用程序中跟踪错误的程序集引用问题的原因。 我正在寻找的并不是有人告诉我问题的确切解决方案,而是如何找到系统试图加载的程序集以及如何找出它为什么这样做。

当我们升级Azure工具时出现了问题。 真正奇怪的是,当我尝试通过Entity Framework调用数据库函数时,错误只发生(从我所知道的)。 EF执行所有这些隐式程序集加载以及一些如何混淆并尝试加载Microsoft.ServiceBus 1.8.0.0(或正在查找该程序集)而不是版本2.2.0.0。

我们正在使用Entity Framework 4.0。 而且,仅供参考,我们可以调用存储过程并进行其他类型的查询。 它只是导致此特定问题的db函数调用。

我通过我的应用程序搜索了高低,并且找不到1.8.0.0的引用,也没有任何杂散的1.8.0.0 dll。 我们可能会对某些第三方库提供过时的参考,这些库继续引用1.8.0.0,但我认为这不太可能。

尽管如此,我的目标不是让某人告诉我X是我的问题,而是告诉我如何监视实体框架并找出为什么它试图加载该程序集以及它期望找到的内容实际发现了什么。

这是我的完整堆栈跟踪。

无法加载文件或程序集“Microsoft.ServiceBus,Version = 1.8.0.0,Culture = neutral,PublicKeyToken = 31bf3856ad364e35”或其依赖项之一。 定位的程序集的清单定义与程序集引用不匹配。 (来自HRESULT的异常:0x80131040)在System.Reflection.RuntimeAssembly的System.Reflection.RuntimeAssembly._nLoad(AssemblyName fileName,String codeBase,Evidence assemblySecurity,RuntimeAssembly locationHint,StackCrawlMark&stackMark,IntPtr pPrivHostBinder,Boolean throwOnFileNotFound,Boolean forIntrospection,Boolean suppressSecurityChecks)中。 InternalLoadAssemblyName(AssemblyName assemblyRef,Evidence assemblySecurity,RuntimeAssembly reqAssembly,StackCrawlMark&stackMark,IntPtr pPrivHostBinder,Boolean throwOnFileNotFound,Boolean forIntrospection,Boolean suppressSecurityChecks)System.Reflection.Assembly.Load(AssemblyName assemblyRef)at System.Data.Metadata.Edm.MetadataAssemblyHelper.SafeLoadReferencedAssembly System.Data.Meta上的System.Data.Metadata.Edm.MetadataAssemblyHelper.d__0.MoveNext()处于System.Data.Meta的System.Data.Metadata.Edm.AssemblyCache.LoadAssembly(Assembly assembly,Boolean loadReferencedAssemblies,ObjectItemLoadingSessionData loadingData)中的(AssemblyName assemblyName) System.Data.Metadata.Edm.AssemblyCache上的System.Data.Metadata.Edm.AssemblyCache.LoadAssembly(Assembly assembly,Boolean loadReferencedAssemblies,ObjectItemLoadingSessionData loadingData)中的data.Edm.AssemblyCache.LoadAssembly(Assembly assembly,Boolean loadReferencedAssemblies,ObjectItemLoadingSessionData loadingData)。在System.Data.Metadata.Edm.AssemblyCache.LoadAssembly(Assembly assembly,Boolean loadReferencedAssemblies,KnownAssembliesSet knownAssemblies,EdmItemCollection edmItemCollection,Action`1 logLoadMessage,Object&loaderCookie,Dictionary`2&typesInLoading,List中的LoadAssembly(Assembly assembly,Boolean loadReferencedAssemblies,ObjectItemLoadingSessionData loadingData) System.Data.Metadata.Edm.ObjectItemCollection.ImplicitLoadAllRe的System.Data.Metadata.Edm.ObjectItemCollection.LoadAssemblyFromCache(ObjectItemCollection objectItemCollection,Assembly assembly,Boolean loadReferencedAssemblies,EdmItemCollection edmItemCollection,Action`1 logLoadMessage)中的`1&errors) 在System.Data.Objects.ObjectContext.CreateQuery [T](String queryString,ObjectParameter []参数)的System.Data.Metadata.Edm.MetadataWorkspace.ImplicitLoadAssemblyForType(Type type,Assembly callingAssembly)中的ferencedAssemblies(汇编程序集,EdmItemCollection edmItemCollection)at c:\\ Users \\ RMacgrogan \\ dev \\ flightbridge \\ BaseOps \\ trunk \\ FB版本7.8 \\ code \\ InternalServices \\ Data \\ Model \\ FlightBridgeDataModel中的Pallas.FlightBridge.Services.Internal.Data.Model.FlightBridgeDatabaseContext.TripPermissions(Nullable`1 companyPersonId) .Designer.cs:第3778行在Pallas.FlightBridge.Services.Internal.Data.Repository.TripRepository.GetTripAndOrdersAndTravelers(Int32 tripId,Int32 companyPersonId)中c:\\ Users \\ RMacgrogan \\ dev \\ flightbridge \\ BaseOps \\ trunk \\ FB Version 7.8 \\ code \\ InternalServices \\ Data \\ Repository \\ TripRepository.cs:第50行

在azure工具升级后,我们遇到了类似的问题。 有了我们的,它正在寻找一个不同版本的Microsoft.WindowsAzure.Storage。 这为我们修好了。 这是来自worker角色的app.config,但同一部分在web.config中也有效:

<runtime>
  <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
    <dependentAssembly>
      <assemblyIdentity name="Microsoft.WindowsAzure.Storage" publicKeyToken="31bf3856ad364e35" />
      <bindingRedirect oldVersion="0.0.0.0-2.1.0.0" newVersion="2.1.0.0" />
    </dependentAssembly>
  </assemblyBinding>
</runtime>

所以对你来说,似乎在有问题的角色的配置文件中需要类似的绑定重定向。 像这样的东西:

<runtime>
  <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
    <dependentAssembly>
      <assemblyIdentity name="Microsoft.ServiceBus" publicKeyToken="31bf3856ad364e35" />
      <bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
    </dependentAssembly>
  </assemblyBinding>
</runtime>

为什么会这样?

当Microsoft构建这些库(如EF,WindowsAzure Storage等)时,它们会依赖其他库。 在构建dll时,他们可能依赖于像Microsoft.ServiceBus这样的库的1.8版本。 通常,这些依赖项是.NET框架的一部分,或类似Azure SDK的一部分。

后来,他们推出了这些库的更新版本。 您的项目可能依赖于较新版本的.NET框架,Azure SDK或特定库,其版本与原始库的依赖关系不同 - 例如2.2而不是1.8。 有问题的库(EF)会查找它针对它编译的版本(1.8),并且即使你有一个更新版本的dll(2.2)可以完美地使用它,也会抛出一个异常。 解决方案是使用绑定重定向配置您的应用程序以告诉依赖项“嘿,可以使用此版本的新版本”。

事实上,如果您有一个多项目解决方案,nuget已经开始在安装新软件包时将这些绑定重定向放在其他项目中。 它基本上告诉解决方案中的所有项目,“嘿,如果你使用这个库,现在解决方案中有一个新版本。使用这个新版本而不是之前使用的任何以前的版本。”

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM