Cosmos DB .NET SDK: 无法找到从未存在的 ‘resources.dll’

huangapple go评论72阅读模式
英文:

Cosmos DB .NET SDK: could not find 'resources.dll' that never existed

问题

是的,我知道这个问题看起来与C# - 'Resources' DLL failing to be loaded as it doesn't exist相似,但我的问题涉及到一个我不拥有的DLL。那个问题涉及到作者自己编写的DLL。

**编辑:**解决问题后,原来是完全相同的情况。我自己标记了我的问题为重复。

背景

我正在编写一个使用Cosmos DB .NET SDK 3.32.2的C#库。有时,这个库会抛出异常,因为它找不到Microsoft.Azure.Cosmos.Direct.resources.dll。这个文件从一开始就不存在Cosmos.Direct DLL内部嵌入了en-US不可变文化资源。是的,我反编译过它以进行检查 - Cosmos.Direct似乎是Cosmos团队没有开源发布的SDK的一部分。

要明确,我无法控制Microsoft.Azure.Cosmos.Direct.dll。这是我的依赖项。值得一提的是,Microsoft.Azure.Cosmos的NuGet包包含四个DLL之一,其中之一是Microsoft.Azure.Cosmos.Direct.dll

FooBar.OurCustomExceptionType: 发生了一个或多个错误。---> System.AggregateException: 发生了一个或多个错误。---> System.IO.FileNotFoundException: 无法加载文件或程序集“file:///C:\Foo\Bar\Microsoft.Azure.Cosmos.Direct.resources.dll”或其依赖项之一。系统找不到指定的文件。

   at System.Reflection.RuntimeAssembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
   at System.Reflection.RuntimeAssembly.InternalGetSatelliteAssembly(String name, CultureInfo culture, Version version, Boolean throwOnFileNotFound, StackCrawlMark& stackMark)
   at System.Resources.ManifestBasedResourceGroveler.GetSatelliteAssembly(CultureInfo lookForCulture, StackCrawlMark& stackMark)
   at System.Resources.ManifestBasedResourceGroveler.GrovelForResourceSet(CultureInfo culture, Dictionary`2 localResourceSets, Boolean tryParents, Boolean createIfNotExists, StackCrawlMark& stackMark)
   at System.Resources.ResourceManager.InternalGetResourceSet(CultureInfo requestedCulture, Boolean createIfNotExists, Boolean tryParents, StackCrawlMark& stackMark)
   at System.Resources.ResourceManager.InternalGetResourceSet(CultureInfo culture, Boolean createIfNotExists, Boolean tryParents)
   at System.Resources.ResourceManager.GetString(String name, CultureInfo culture)
   at Microsoft.Azure.Documents.StoreResult.CreateStoreResult(StoreResponse storeResponse, Exception responseException, Boolean requiresValidLsn, Boolean useLocalLSNBasedHeaders, Uri storePhysicalAddress)
   at Microsoft.Azure.Documents.StoreReader.<ReadMultipleReplicasInternalAsync>d__14.MoveNext()
   
   ... 较长的堆栈跟踪 ...

   at FooBar.OurCustomCosmosWrapper`1.<GetItemAsync>d__4.MoveNext()

从堆栈跟踪来看,该库正在搜索从未存在的资源的“卫星程序集”,尽管资源已嵌入在DLL中。

我已经设置了自己的应用使用[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.MainAssembly)]在AssemblyInfo.cs中,但显然这不影响这个Cosmos依赖库。它只影响了我的自己的FooBar库,它依赖于Cosmos SDK。

我的问题

如何强制我的一个依赖DLL(在这种情况下,Microsoft.Azure.Cosmos.Direct.dll)使用其自己的嵌入资源,而不是尝试找到一个不存在的resources.dll文件?

我认为这可能是以下几个问题之一:

  • 有一种方法可以在App.config或其他项目配置文件中设置依赖程序集资源加载,我不知道。请记住:我不需要为自己的库设置这个;我需要为我的一个依赖设置这个。
  • 这是Cosmos SDK中的一个bug。
  • 在导入Microsoft.Azure.Cosmos包时,我错过了与文化相关的某个设置。
英文:

Yes, I know this question looks similar to C# - 'Resources' DLL failing to be loaded as it doesn't exist, but my question is about a DLL that I do not own. That other question involves the author's own DLL that they wrote.

EDIT: after solving the problem, it turns out to have been the exact same scenario. I have self-flagged my own question as a duplicate.

Background

I am writing a C# library that uses the Cosmos DB .NET SDK 3.32.2. Sometimes, this library throws an exception because it could not find Microsoft.Azure.Cosmos.Direct.resources.dll. This file never existed in the first place; the Cosmos.Direct DLL ships with en-US invariant culture resources embedded inside the DLL. Yes, I decompiled it to check - Cosmos.Direct seems to be part of the SDK that the Cosmos team didn't release as open-source.

To be clear, I do not control Microsoft.Azure.Cosmos.Direct.dll. That is my dependency. FYI, the NuGet package for Microsoft.Azure.Cosmos ships with four DLLs, one of them being Microsoft.Azure.Cosmos.Direct.dll.

FooBar.OurCustomExceptionType: One or more errors occurred. ---> System.AggregateException: One or more errors occurred. ---> System.IO.FileNotFoundException: Could not load file or assembly 'file:///C:\Foo\Bar\Microsoft.Azure.Cosmos.Direct.resources.dll' or one of its dependencies. The system cannot find the file specified.

   at System.Reflection.RuntimeAssembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
   at System.Reflection.RuntimeAssembly.InternalGetSatelliteAssembly(String name, CultureInfo culture, Version version, Boolean throwOnFileNotFound, StackCrawlMark& stackMark)
   at System.Resources.ManifestBasedResourceGroveler.GetSatelliteAssembly(CultureInfo lookForCulture, StackCrawlMark& stackMark)
   at System.Resources.ManifestBasedResourceGroveler.GrovelForResourceSet(CultureInfo culture, Dictionary`2 localResourceSets, Boolean tryParents, Boolean createIfNotExists, StackCrawlMark& stackMark)
   at System.Resources.ResourceManager.InternalGetResourceSet(CultureInfo requestedCulture, Boolean createIfNotExists, Boolean tryParents, StackCrawlMark& stackMark)
   at System.Resources.ResourceManager.InternalGetResourceSet(CultureInfo culture, Boolean createIfNotExists, Boolean tryParents)
   at System.Resources.ResourceManager.GetString(String name, CultureInfo culture)
   at Microsoft.Azure.Documents.StoreResult.CreateStoreResult(StoreResponse storeResponse, Exception responseException, Boolean requiresValidLsn, Boolean useLocalLSNBasedHeaders, Uri storePhysicalAddress)
   at Microsoft.Azure.Documents.StoreReader.<ReadMultipleReplicasInternalAsync>d__14.MoveNext()
   
   ... long stack trace ...

   at FooBar.OurCustomCosmosWrapper`1.<GetItemAsync>d__4.MoveNext()

Looking at the stack trace, the library is searching for a "satellite assembly" of resources that never existed, even though the resources are embedded in the DLL.

I have set my own app to use [assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.MainAssembly)] in AssemblyInfo.cs, but clearly that is not affecting this Cosmos dependency library. It only affects my own FooBar assembly that takes a dependency on the Cosmos SDK.

My question

How do I force my one of my dependency DLLs (in this case, Microsoft.Azure.Cosmos.Direct.dll) to use its own embedded resources instead of trying to find a separate resources.dll file that doesn't exist?

I bet this could be one of a few problems:

  • There is some way to set dependency assembly resource loading in App.config or some other project config file that I don't know about. Remember: I don't need to set this for my own library; I need to set this for one of my dependencies.
  • This is a bug in the Cosmos SDK.
  • I missed a culture-related setting somewhere when importing the Microsoft.Azure.Cosmos package.

答案1

得分: 0

抱歉,你提供的内容包含了代码部分,根据你的要求,我只会翻译非代码的部分。以下是翻译好的内容:

"It was not Cosmos's fault; we actually had an AppDomain.AssemblyResolve handler registered somewhere else that was intercepting assembly loads, even if they were embedded assemblies, and was attempting to load them from a specific location as a .dll file. This file never existed, so it would fail."

"That SO post I originally mentioned in my question? C# - 'Resources' DLL failing to be loaded as it doesn't exist

It did in fact solve the problem. Just search your repo for AssemblyResolve, check to see if a handler function was registered for it, then makes sure that handler returns null (or nullptr if in C++) when it encounters one of your embedded resource assemblies."

英文:

It was not Cosmos's fault; we actually had an AppDomain.AssemblyResolve handler registered somewhere else that was intercepting assembly loads, even if they were embedded assemblies, and was attempting to load them from a specific location as a .dll file. This file never existed, so it would fail.

That SO post I originally mentioned in my question? C# - 'Resources' DLL failing to be loaded as it doesn't exist

It did in fact solve the problem. Just search your repo for AssemblyResolve, check to see if a handler function was registered for it, then makes sure that handler returns null (or nullptr if in C++) when it encounters one of your embedded resource assemblies.

huangapple
  • 本文由 发表于 2023年4月4日 05:11:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/75923805.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定