3

I am trying to use the AssemblyResolve method to load embedded assemblies. However one of these appears to refer to itself, and so when trying to load it, it calls the AssemblyResolve again.

AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
{
    using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(string.Format("AnalysisViewer.Embedded_DLLs.{0}.dll", new AssemblyName(args.Name).Name)))
    {
        if (stream == null)
            return null;
        byte[] assemblyData = new byte[stream.Length];
        stream.Read(assemblyData, 0, assemblyData.Length);
        return Assembly.Load(assemblyData);
    }

};

Is there a way round this? The dll being loaded is a DevExpress one, so I cannot do anything about the code in that, and it loads fine if I have it as a standard dll.

I can revert to distributing this dll with the package, but we are trying to get a single file drop installation, if possible.

This is the stack trace I get:

AnalysisViewer.exe!AnalysisViewer.App.OnStartup.AnonymousMethod__0(object sender, System.ResolveEventArgs args)
mscorlib.dll!System.AppDomain.OnAssemblyResolveEvent(System.Reflection.RuntimeAssembly assembly, string assemblyFullName)
[Native to Managed Transition]  
mscorlib.dll!System.AppDomain.OnAssemblyLoadEvent(System.Reflection.RuntimeAssembly LoadedAssembly)
[Native to Managed Transition]  
mscorlib.dll!System.Reflection.Assembly.Load(byte[] rawAssembly)
AnalysisViewer.exe!AnalysisViewer.App.OnStartup.AnonymousMethod__0(object sender, System.ResolveEventArgs args)
Schroedingers Cat
  • 3,099
  • 1
  • 15
  • 33
  • What does the stack look like in the reentrant call? Judging by the docs, `AssemblyResolve` shouldn't be called for `Assembly.Load(byte[])` so perhaps it's something else? Or do you mean that it's only a problem *because* the assembly refers to itself? Have you tried returning null if you detect reentrancy? (It sounds like aside from anything else, you should ask DevExpress to fix that...) – Jon Skeet Aug 27 '15 at 09:21
  • I couldn't get a stack trace, because the stack overflow killed it. I was stepping through to see what was happening, and at the Assembly.Load() it was definitively calling the Resolve again. – Schroedingers Cat Aug 27 '15 at 09:24
  • Right - so you can get a "manual" stack trace by just putting a break point on your `return` statement and hitting "go" a few times. If you could include that, along with `args.Name` for each call to your event handler, that would help to explain things. – Jon Skeet Aug 27 '15 at 09:25
  • If I can prove that it is a DE issue, I will contact them. I tried caching the loaded dlls, so that it would not have to load them again, but it was re-calling the Resolve before I could load and cache the previous entry call. – Schroedingers Cat Aug 27 '15 at 09:25
  • OK, let me have a go. – Schroedingers Cat Aug 27 '15 at 09:26
  • Well, you say that it "appears to refer to itself" - how have you determined that? I'd use `ildasm` to look at the references... – Jon Skeet Aug 27 '15 at 09:26
  • "appears to refer to itself" was merely because of the recursive calls. The stack trace does seem to reflect this too. There is one more aspect that might be an issue, so I will try this. – Schroedingers Cat Aug 27 '15 at 10:24
  • Right, so presumably you now have a stack of names that it's attempting to resolve? – Jon Skeet Aug 27 '15 at 10:25
  • Edited into the question. – Schroedingers Cat Aug 27 '15 at 10:38
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/88083/discussion-between-schroedingers-cat-and-jon-skeet). – Schroedingers Cat Aug 27 '15 at 10:41
  • Assembly.Load(byte[]) is a recipe for DLL Hell. The assembly gets loaded without a loading context, lots of things can go wrong in a very hard to diagnose way. The stack overflow otherwise fits the behavior of what goes wrong with a retargetable assembly, covered in [this Q+A](http://stackoverflow.com/questions/18793959/filenotfoundexception-when-trying-to-load-autofac-as-an-embedded-assembly). – Hans Passant Aug 27 '15 at 12:11
  • Hans - I am well aware of the possible dangers of doing this. I would not try this with core DLLS, but I had hoped that the DE files would be well enough behaved to allow this to work for me. – Schroedingers Cat Aug 27 '15 at 14:03

1 Answers1

2

OK, this might prove useful to someone. It seems that the problem was that a DE dll was calling other dlls that were not available. I thought I had traced through all of the required dlls but it seems like I had missed some. Once I included these, it processed as expected.

However, at no point in the failing did it tell me what dlls it was trying to find. Which is why it was so frustrating.

Schroedingers Cat
  • 3,099
  • 1
  • 15
  • 33