【问题标题】:Assembly resolve at runtime程序集在运行时解析
【发布时间】:2017-09-20 18:39:31
【问题描述】:

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

这段代码应该如何工作?

【问题讨论】:

  • 我认为print 是一些仅用于调试的方法(例如调用堆栈),并不意味着加载的程序集中包含的东西。 athhor 应该已经在前面的章节中给出了代码。

标签: c# .net assemblies resolver


【解决方案1】:

如果编译,因为大概你有一个MainClass 类型和Print 方法对库的a 引用,即使它是一个没有任何实际的空存根实施 - 或者只是错误的实施。这不是“未知”。如果它是未知的,那么这段代码确实无法编译,你必须在运行时使用反射来查找类型,并使用反射来实例化实例,并使用反射来调用@987654323 @ 方法(除非有一些众所周知的接口或基类可以转换为,或者你使用dynamic)。

这就是编译某些东西所需的全部内容:元数据。事实上,相对普遍以“参考库”为目标——这正是你的 IDE 中的多目标特性的工作量。

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

【讨论】:

  • 但是如果我添加空存根作为项目的引用,ResolveAssembly 会在出现new MainClass() 时引发?
  • @nrofis 它会在 JIT 需要它的时候发生,所以 最迟 new MainClass() 运行时,但可能更早
  • 即使MainClass 已知并且存在于引用中?
【解决方案2】:

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

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

【讨论】:

    猜你喜欢
    • 2015-05-22
    • 2013-09-09
    • 2012-03-13
    • 2013-03-12
    • 1970-01-01
    • 2022-11-24
    • 1970-01-01
    • 2012-08-02
    • 1970-01-01
    相关资源
    最近更新 更多