0

I have a service that involves downloading an assembly from cloud storage, creating an instance of it using Activator.CreateInstance and then invoking a method on it.

I have set up a AssemblyResolve method to download dependencies which works fine, but to test/experiment I am now trying to manually download assemblies. I have got as far as finding which dependencies are needed, downloading them and then loading them using

Assembly.Load(byte[])

After which I can see they are loaded into the AppDomain via

AppDomain.CurrentDomain.GetAssemblies())

However when I am invoking the method on the assembly which references this, it still goes to the AssemblyResolver.

I may be misunderstanding how loaded assemblies and the AppDomain works but it seems to me that once the assembly is loaded it should be available to this assembly and it shouldn't need to resolve it?

Why can't it "see" it? The version and name etc is the same.

I have read about the different assembly binding contexts here and I think this could be the issue? It suggests that using Assembly.Load(string) will load to a different context than Assembly.Load(byte)? In which case how do I do this when I just have the assembly in memory as a byte[]?

Thanks

QTom
  • 1,441
  • 1
  • 13
  • 29
  • Does it fail to load the assembly even though you have already use Assembly.Load(..) with no exception? – Redhead Dec 20 '16 at 16:47
  • Can you show a screenshot of your `Debug->Widnows->Modules` screen in Visual Studio after the assembly has been loaded with the assebly selected? – Scott Chamberlain Dec 20 '16 at 16:47
  • Please add the code that shows how you load the type, get the method and execute it. I've taken an educated guess at what the problem is though ;-) – RB. Dec 20 '16 at 17:03
  • @Redhead there's no error because it will just resolve the dependencies via the AssemblyResolve event, what I'm wondering is why it can't just use the assemblies that I have already loaded manually and I can see in AppDomain.GetAssemblies() – QTom Dec 21 '16 at 09:20

1 Answers1

0

You need to obtain the Type directly from the assembly you loaded, as it is not loaded into the correct context.

var assembly = Assembly.Load(File.ReadAllBytes(some_path));

// This will work. Note that you don't need the assembly-qualified name,
// as you are asking the assembly directly for the type.
var type1 = assembly.GetType("My.Special.Type");

// This will not work - the assembly "My.Assembly" is not loaded into
// the Load context, so the type is not available.
var type2 = Type.GetType("My.Special.Type, My.Assembly");

In the code above, type1 will have a reference to the Type, but type2 will be null, as the assembly is not loaded into the normal Load context.

RB.
  • 36,301
  • 12
  • 91
  • 131
  • This is what we are doing with the assembly we actually run, the problem is the dependencies that I have loaded with Assembly.Load(byte[]) can apparently not be used so when I run the method from that type it triggers the AssemblyResolve event even though the assemblies it wants are already loaded in the AppDomain. – QTom Dec 21 '16 at 09:19