【问题标题】:Reference has not compile-time usages参考没有编译时用法
【发布时间】:2018-02-06 13:29:49
【问题描述】:

我一直在关注 ReSharper 创建的解决方案的架构视图,当我注意到一些项目引用没有编译时用法时,这是否意味着我可以在运行时更改程序集?

【问题讨论】:

    标签: c# .net resharper assemblies


    【解决方案1】:

    简单来说,没有编译时使用意味着即使您删除了引用,您的代码也会编译。您不能从该语句中直接派生有关运行时的任何内容。如果您只是删除此引用,您的应用程序甚至可能运行得非常好。也可能是您的引用有些混淆,编译器不知道。这可能是因为该引用正在实现您编译的接口,或者您正在运行时手动查找它(请参阅 Florians 答案)。如果你真的想的话,你也可以用反射来隐藏它。但这也需要在运行时手动加载程序集。

    在编译时,编译器会将新的二进制文件链接到引用程序集中的相应代码。这将允许在运行时自动加载程序集。它还将 const 值复制到您的程序集。

    您绝对可以在编译和运行时更改引用的程序集,尽管您应该非常小心。如果方法签名更改,编译时引用将中断。

    在运行时,一旦您尝试与引用的程序集进行交互,就会加载它们。程序集一旦加载,就不能直接卸载。您只能卸载 AppDomain。因此,如果您想在运行时更改程序集,请查看 AppDomains。

    那么这些非编译时引用的预期用途是什么? Florian 在另一个答案中提到了使用此功能的最常见架构:插件。还有其他依赖项,您希望通过接口将代码与实际实现分开。没有编译时依赖项的项目引用仅用于将实现交付给实际应用程序。否则,您需要将此添加到您的交付和调试过程中,这取决于您的项目,这可能会很痛苦。

    【讨论】:

    • 所以我用其中的项目编译我的解决方案。它们现在是我的工作目录中的程序集。所以在我的解决方案中,我有 2 个项目没有编译时使用,这是否意味着我可以单独编译其中 1 个项目(不是整个解决方案),现在我有工作目录(带有旧版本的项目 1 程序集)和新创建的项目 1 的程序集。所以您是说我可以通过使用 AppDomains 将新创建的程序集更改为我的工作目录中的旧程序集,而进程仍在运行(可能有一些停机时间)?
    • 这样做的重点是尽可能减少停机时间,而无需启动此过程的新实例,因为例如我的解决方案可能需要大量时间来编译/优化等等我不'每次我对没有编译时使用的项目进行更改时,我都不想通过该过程
    • 是的,如果您使用 AppDomains,您应该能够设置一些逻辑来实现这一点。看看例如brad-smith.info/blog/archives/500 一些想法
    猜你喜欢
    • 2016-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-09
    相关资源
    最近更新 更多