手动加载程序集

时间:2016-02-26 19:44:52

标签: c# .net

我刚刚遇到了一个我以前没见过的装配参考问题。在我通常的生产代码中,我的加载器应用程序通过将原始字节传递给Assembly.Load然后调用入口点来加载主应用程序集(和其他引用)。

今天我需要让主应用程序动态加载另一个引用(以下称为'dll'),它包含一个继承自主程序中基类的类。这在直接运行主应用程序时工作正常。当通过加载器运行它时,主应用程序加载dll就好了,但它似乎不知道当前加载的主应用程序与dll引用的应用程序相同。因此,向基类投射显然是行不通的。我被卡住了。

我假设主应用程序集正以某种方式失去了它的身份。

以下是一些说明问题的代码:

// main application
namespace Program1
{
    public class BaseClass { }

    class Program
    {
        static void Main( string[] args )
        {
            string s = "Library1.Class1, Library1";            
            var t = Type.GetType( s, true );
            Debug.Assert( t.IsSubclassOf( typeof( BaseClass ) ) );
        }
    }    
}

// dll
namespace Library1
{
    public class Class1 : Program1.BaseClass { }
}

// loader
class Program
{
    static void Main( string[] args )
    {
        var bytes = File.ReadAllBytes( "Program1.exe" );
        var asm = Assembly.Load( bytes );
        var e = asm.EntryPoint;
        e.Invoke( null, new object[] { null } );
    }
}

当直接运行Program1时,它可以工作,当通过加载器运行它时,断言失败。

那么,任何人都可以解释这里发生了什么 - 如果有可能解决它吗?

1 个答案:

答案 0 :(得分:1)

如果(让我们调用dllA和dllB你的库),dllA有一个对dllB的引用,你加载dllA并且它没有崩溃,这意味着.net已经自动解析并加载了dllB。

然后当你再次加载dllB它是另一个程序集,然后类型不匹配时,我用dll加载系统运行了很多次这种情况,最后添加引用的库更好(在这种情况下dllB)在.exe文件夹中,让系统在你加载dllA时自动加载它。

如果需要对库的引用,另一个选项是在加载DllA之前附加到AssemblyResolve事件,然后当你加载它时,事件将触发,要求你加载DllB,因此你可以存储对库的引用。 / p>