当程序集用作子类时,CurrentDomain.AssemblyResolve不会触发

Jim*_*Jim 8 c# assemblies embedded-resource

我正在尝试使用该CurrentDomain.AssemblyResolve事件来加载标记为嵌入式资源的DLL.我的问题,具体来说,是因为我试图将程序集用作子类,如下所示:

#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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

测试类SubClass定义为:

namespace TestCompanyInc
{
    public class SubClass
    {
        public SubClass()
        {
            TestProperty = "Init'd";
        }
        public string TestProperty { get; set; }
    }
}
Run Code Online (Sandbox Code Playgroud)

如果第一行#define BROKEN未被注释,那么CurrentDomain.AssemblyResolve事件将永远不会触发,并且抛出System.IO.FileNotFoundException,并且我被告知SubClass无法找到.如果第一行被删除或注释掉,那么它将触发事件(但我不能以这种方式使用它).

我也试过Main进入自己的类,而不是让同一个类创建自己的实例,但我得到完全相同的异常.

那么,如何才能正确连接此事件,以便在这些条件下加载此程序集?


在VS 2010 .NET 4中编译,如果这对任何人都有影响.此外,对于任何试图重新创建这个的人.SubClass在自己的项目中.添加SubClass作为对TestConsole的引用,并将其标记为Copy Local = False.我在某处读过,这不是项目参考,而是直接引用DLL.然后,将DLL 文件添加到TestConsole项目并将其标记为嵌入式资源,而不是默认的Content.

Mar*_*ell 20

想想加载顺序...为了JIT并调用Main,它必须理解Program.在没有加载基类的情况下它无法理解程序,这需要特殊的处理.该事件未触发,因为它尚未注册(因为Main尚未启动).

那不行.你能做到这一点的唯一方法就是拥有一个不依赖于任何其他东西的入口点.请注意,JIT在方法开始之前完成,因此Main也不会涉及任何未知的内容.例如,您可能会这样做:

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

注意我们需要2种方法,因为它不能JIT Main,除非它可以完全解析Program.有了上述内容,事件应该在调用MainCore()之前触发(即在JIT for MainCore期间).