You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何强制Cosmos DB依赖DLL使用内嵌资源,避免寻找不存在的resources.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,其中就有这个文件。

异常信息

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()

从栈跟踪来看,这个依赖库在寻找根本不存在的资源附属程序集,哪怕资源已经内嵌在DLL里了。我已经在自己的AssemblyInfo.cs中设置了[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.MainAssembly)],但这只影响我自己的FooBar程序集,对Cosmos的依赖库无效。

我的核心问题是:如何强制依赖DLL(这里是Microsoft.Azure.Cosmos.Direct.dll)使用自身内嵌的资源,而不是尝试寻找不存在的独立resources.dll文件?

可能的原因

  • 存在某种在App.config或其他项目配置文件中设置依赖程序集资源加载的方式(需针对依赖库而非自身库);
  • Cosmos SDK存在bug;
  • 导入Microsoft.Azure.Cosmos包时遗漏了某些区域性相关设置。
解决方案

1. 配置应用默认区域性

强制应用使用en-US区域性,避免触发非中性资源的查找逻辑:

  • 对于.NET Framework项目,在App.config/Web.config中添加:
<configuration>
  <system.web>
    <globalization culture="en-US" uiCulture="en-US" />
  </system.web>
</configuration>
  • 对于.NET Core/.NET 5+项目,在启动代码中设置:
CultureInfo.DefaultThreadCurrentCulture = CultureInfo.GetCultureInfo("en-US");
CultureInfo.DefaultThreadCurrentUICulture = CultureInfo.GetCultureInfo("en-US");

2. 拦截AssemblyResolve事件

通过订阅AppDomain.AssemblyResolve事件,当系统尝试加载不存在的资源附属DLL时,返回主程序集:

AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
{
    var assemblyName = new AssemblyName(args.Name);
    if (assemblyName.Name.Equals("Microsoft.Azure.Cosmos.Direct.resources", StringComparison.OrdinalIgnoreCase))
    {
        return Assembly.Load("Microsoft.Azure.Cosmos.Direct");
    }
    return null;
};

这个逻辑会让资源管理器直接使用主DLL中的内嵌资源,跳过对附属程序集的查找。

3. 升级Cosmos SDK版本

如果是SDK自身的bug,尝试升级到更高版本的Microsoft.Azure.Cosmos NuGet包,后续版本大概率修复了这类资源加载问题。

4. 临时 workaround:手动创建资源DLL

如果上述方法都无效,可以反编译Microsoft.Azure.Cosmos.Direct.dll提取内嵌资源,手动生成Microsoft.Azure.Cosmos.Direct.resources.dll并放入en-US目录中,但这只是临时方案,不推荐长期使用。


内容的提问来源于stack exchange,提问作者Phil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 23:57:05