I have a C#.NET class library, ClassLib
, which uses both Newtonsoft.Json
and RestSharp
.
The idea of the library is that it is an API "super-wrapper" that is included in third-party end-user applications, eg desktop apps, web apps, Windows services, etc.
In order to keep things self-contained, I've embedded Newtonsoft and RestSharp in ClassLib using the embedded resources and AssemblyResolve approach discussed in several threads on SO.
So far, so banal; I've used this approach several times in different projects such as plug-ins and everything generally works as expected.
This time, however, I've hit a weird snag. And it's inconsistent.
I use ClassLib in a couple of small desktop app projects which demonstrate ClassLib's capabilities as well as a main production project.
Everything works perfectly in the demo projects, and was working fine in the production project. But the production project has just started throwing an assembly not found error:
"Could not load file or assembly 'RestSharp, Version=100.0.0.0, Culture=neutral, PublicKeyToken=598062e77f915f75' or one of its dependencies. General Exception (Exception from HRESULT: 0x80131500)":"RestSharp, Version=100.0.0.0, Culture=neutral, PublicKeyToken=598062e77f915f75"
I've tried to get the demo project to throw this error by running it with ClassLib.dll on four other machines which don't have RestSharp registered anywhere I can find but it runs perfectly.
But no matter what I do with the production project - which is running on a machine where there are multiple extraneous copies of RestSharp but nothing in the GAC that I can find - it continues to fail on this error.
The thing is, though, it was fine until yesterday.
So, of course, something has changed somewhere to create the issue, I just don't know what it is.
Any ideas?
Ok, got it.
Both ClassLib and the main production project ("Product") implement(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;
}
However, the demonstration projects didn't as they have no embedded assemblies to extract.
So what was happening was that when Product didn't find RestSharp, it called GetMissingAssembly
, reasonably enough, and when it wasn't found in the assembly collection, threw the designated error.
However, if I simply continue through the handler returning a null result, the reference ends up being resolved within ClassLib - as it should be - and everything is fine.
Whatever changed, I don't know yet - and I mightn't bother looking, to be honest - but the solution is to either 1) don't throw an error and just return null, 2) ignore any search for RestSharp explicitly or, probably best, 3) check whether an embedded assembly itself embeds the missing assembly and exit knowing it will be resolved.
* As mentioned, I ended up moving to Costura in ClassLib rather than handling AssemblyResolve
myself. I'll do the same in Product and see if this works or not and post back. I'd hope that the writers on Costura have thought of this scenario but we'll see.
PS Thanks to Parish Husband for suggesting I check bitness; I did find a couple of things I needed to correct, though that wasn't the issue.
User contributions licensed under CC BY-SA 3.0