我有一个C#.NET类库ClassLib
,它使用Newtonsoft.Json
和RestSharp
。
该库的想法是它是一个API“超级包装器”,包含在第三方最终用户应用程序中,例如桌面应用程序,Web应用程序,Windows服务等。
为了保持自包含,我使用在SO上的几个线程中讨论的嵌入式资源和AssemblyResolve方法在ClassLib中嵌入了Newtonsoft和RestSharp。
到目前为止,如此平庸;我在不同的项目中多次使用这种方法,例如插件,一切都按预期工作。
然而,这一次,我遇到了一个奇怪的障碍。而且它不一致。
我在几个小型桌面应用程序项目中使用ClassLib,这些项目演示了ClassLib的功能以及主要的生产项目。
一切都在演示项目中完美运行,并且在生产项目中运行良好。但是生产项目刚刚开始抛出一个未找到的程序集错误:
“无法加载文件或程序集'RestSharp,Version = 100.0.0.0,Culture = neutral,PublicKeyToken = 598062e77f915f75'或其依赖项之一。常规异常(HRESULT异常:0x80131500)”:“RestSharp,Version = 100.0.0.0, Culture = neutral,PublicKeyToken = 598062e77f915f75“
我试图通过在其他四台没有RestSharp注册的机器上运行ClassLib.dll来使示例项目抛出此错误,但是它运行完美。
但无论我对生产项目做了什么 - 它在一台机器上运行,其中有多个无关的RestSharp副本,但我找不到GAC中的任何内容 - 它仍然在这个错误上失败。
但问题是,直到昨天才行。
所以,当然,某些地方已经发生变化以创造问题,我只是不知道它是什么。
有任何想法吗?
好的,我知道了。
ClassLib和主要生产项目(“Product”)都实现了(ed *)AssemblyResolve
:
internal static Assembly GetMissingAssembly(
object s,
ResolveEventArgs e)
{
Assembly oResult = null;
if (!e.Name.ToLower().Contains("resources"))
{
string Name = e.Name; //e.Name is read-only
if (moAssemblies != null && moAssemblies.Count > 0)
{
if (moAssemblies.ContainsKey(Name)) oResult = moAssemblies[Name];
if (oResult == null) throw new Exception("Could not load assembly " + Name);
}
}
return oResult;
}
但是,示范项目没有,因为它们没有要提取的嵌入式程序集。
所以发生的事情是,当Product没有找到RestSharp时,它足够合理地调用GetMissingAssembly
,并且当在程序集集合中找不到它时,抛出指定的错误。
但是,如果我只是继续通过处理程序返回null结果,那么引用最终会在ClassLib中解析 - 应该是 - 并且一切都很好。
无论发生了什么变化,我还不知道 - 我可能也不愿意看,说实话 - 但解决办法是:1)不抛出错误而只返回null,2)忽略任何明确的RestSharp搜索或,可能是最好的,3)检查嵌入式装配体是否嵌入缺失的装配体并退出,知道它将被解决。
*如上所述,我最终在ClassLib中移动到Costura,而不是自己处理AssemblyResolve
。我会在产品中做同样的事情,看看这是否有效并发回。我希望Costura的作家能想到这种情况,但我们会看到。
PS感谢Parish Husband建议我检查一下比特;我确实找到了一些我需要纠正的事情,尽管那不是问题。