2017-04-24 52 views
3

我想用AssemblyResolver事件在我的应用程序中动态加载程序集,但我不明白该怎么做。运行时程序集解析

我已经看到这个tutorial并自己尝试过。 在尖端3,他写道:

static void Main(string[] args) 
{ 
    AppDomain.CurrentDomain.AssemblyResolve += ResolveAssembly; 
} 
static void Print() 
{ 
    var mainClass = new MainClass(); 
    mainClass.Print(); 
} 

static Assembly ResolveAssembly(object sender, ResolveEventArgs args) 
{ 
    return Assembly.LoadFile(@"path to the library"); 
} 

其实我不明白这个代码应如何编译在所有... 的new MainClass()不能编译,因为它未知的类型(还没有加载)的加载发生在运行时。
如果MainClass是已知类型,则根本不应解析...

该代码应如何工作?

+0

我认为'print'是一些仅用于调试的方法(如调用堆栈),并不意味着加载的程序集中包含的东西。在先前的章节中应该给出这个代码。 –

回答

0

如果你想加载一个你不知道内容的程序集(然后使用反射来实例化它的类),你可以简单地使用Assembly.Load(),如果你有它的全名(名字,版本,文化和公钥令牌如果存在)或Assembly.LoadFrom如果您有它的路径名。

AssemblyResolve用于“重定向”在编译时“已知”但在运行时必须从特定路径加载的程序集的加载。你可以明确地使用它来“诱饵和切换”程序集(在编译时你有一个程序集,在运行时加载一个实现相同类的不同程序集)。

0

如果编译因为那时你有一个参考到图书馆与MainClass型和Print方法,即使是没有任何实际执行一个空存根 - 或者只是错误的执行。它不是“未知的”。如果它是未知的,那么这个代码实际上不会编译,你必须使用反射来在运行时查找类型,反射来实例化实例,反射来调用Print()方法(除非有一些着名的接口或基础类,你可以投到,或者你使用dynamic)。

这就是你需要编译的东西:元数据。实际上,它是相对常见的,目标是“参考库”,这正是您的IDE中多个多目标功能的工作原理。

运行,您可以覆盖负载提供预期库,但说实话这是通常更容易只是部署实际库到应用程序的探测路径(S)(通常:在主exe文件旁边)。此外,在您的ResolveAssembly方法中,最好检查正在请求哪个程序集 - 它可能试图加载完全不相关的东西,在这种情况下,请将其单独放置。

+0

但是,如果我将空stub添加为项目的引用,当出现'New MainClass()'时,将会引发'ResolveAssembly'? – nrofis

+0

@nrofis它会发生在JIT需要它的时候,所以*在最新的时候*当'new MainClass()'运行时,但可能更早 –

+0

即使'MainClass'已知并且存在于引用中? – nrofis

相关问题