CurrentDomain.AssemblyResolve does not fire when the assembly is used as a subclass

I am trying to use the CurrentDomain.AssemblyResolve event to load a DLL marked as an embedded resource. My problem, in particular, is related to the fact that I'm trying to use the assembly as a subclass, for example:

 #define BROKEN using System; using System.Reflection; using TestCompanyInc; namespace TestConsole { #if BROKEN // This is how I NEED to use it class Program : SubClass #else // This is only here as a test to make sure I wired // CurrentDomain.AssemblyResolve correctly class Program #endif { static int Main(string[] args) { AppDomain.CurrentDomain.AssemblyResolve += (sender, eventArgs) => { string resourceName = Assembly.GetExecutingAssembly() .GetName().Name + "." + new AssemblyName(eventArgs.Name).Name + ".dll"; Console.WriteLine("About to lookup {0}", resourceName); using (var stream = Assembly.GetExecutingAssembly() .GetManifestResourceStream(resourceName)) { byte[] assemblyData = new byte[stream.Length]; stream.Read(assemblyData, 0, assemblyData.Length); return Assembly.Load(assemblyData); } }; Program p = new Program(args); return p.Run(); } public Program(string[] args) { } public int Run() { #if BROKEN // This is how I NEED to use it Console.WriteLine(TestProperty); #else // This is only here as a test to make sure I wired // CurrentDomain.AssemblyResolve correctly SubClass sc = new SubClass(); Console.WriteLine(sc.TestProperty); #endif Console.ReadKey(); return 0; } } } 

The SubClass testing SubClass is defined as:

 namespace TestCompanyInc { public class SubClass { public SubClass() { TestProperty = "Init'd"; } public string TestProperty { get; set; } } } 

If the first line of #define BROKEN left CurrentDomain.AssemblyResolve event CurrentDomain.AssemblyResolve never be fired, and a System.IO.FileNotFoundException will be thrown, and I was told that SubClass could not be found. If the first line is deleted or commented out, then it will fire an event (but I cannot use it that way).

I also tried moving Main to my own class instead of having the same class instantiate itself, but I get the exact same exception.

So, how can I properly connect this event to load this assembly in these conditions?


Compiled in VS 2010.NET 4, if that matters to anyone. Also for those trying to recreate this. SubClass is in its own project. Add SubClass as a reference to TestConsole and mark it as Copy Local = False. I read somewhere that this cannot be a link to a project, but a direct link to a DLL. Then add the DLL file to the TestConsole project and mark it as an embedded resource, not the default for the content.

+8
c # embedded-resource assemblies
source share
1 answer

Think about loading ... In order for JIT to call Main, it must understand the Program. He cannot understand the program without loading the base class, which requires special processing. The event does not fire because it has not yet been registered (since Main is not running).

This will not work. The only way to do this is to have an entry point that is independent of anything else. Note that JIT is executed before the method runs, so Main also cannot include anything that is unknown. For example, you can:

 class Loader { static void Main() { // not shown: register assemy-load here MainCore(); } [MethodImpl(MethodImplOptions.NoInlining)] static void MainCore() { // your class as shown is Program Program.Init(); } } 

Please note that we need 2 methods above, since it cannot JIT Main if it cannot fully resolve the Program. The above event should fire just before calling MainCore () (Ie During JIT for MainCore).

+19
source share

All Articles