程序集在运行时解析

时间:2017-04-24 07:21:14

标签: c# .net assemblies resolver

我想在我的应用中使用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是已知类型,则根本不应该解决...

此代码应如何工作?

2 个答案:

答案 0 :(得分:0)

如果要加载一个您不了解内容的程序集(然后使用反射来实例化其类),如果您有其全名(名称,版本),则可以使用Assembly.Load() ,文化和公钥标记(如果存在),或Assembly.LoadFrom如果您有其路径名。

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

答案 1 :(得分:0)

如果编译,因为您可能会使用MainClass类型和Print方法对库进行 引用,即使它是空的没有任何实际实现的存根 - 或者只是错误的实现。它不是"未知"。如果 未知,那么这段代码确实无法编译,你必须使用反射在运行时查找类型,并反射实例化实例,并反射到调用Print()方法(除非你可以使用某些众所周知的接口或基类,或者使用dynamic)。

这就是编译内容所需的全部内容:元数据。事实上,目标"参考库" 相对常见正是如此 - 这正是IDE中多少目标功能的工作原理。

运行时,您可以覆盖负载以提供预期的库,但说实话,部署实际通常更容易>库进入应用程序的探测路径(通常:在主exe旁边)。此外,在您的ResolveAssembly方法中,最好检查正在请求哪个程序集 - 它可能正在尝试加载完全不相关的内容,在这种情况下只是不管它。