【问题标题】:.NET substitute dependent assemblies without recompiling?.NET 替换依赖程序集而不重新编译?
【发布时间】:2010-04-07 19:32:16
【问题描述】:

我有一个关于 .NET 框架 (2.0) 如何解析依赖程序集的问题。

我们目前正在对一个大型 ASP.NET 应用程序和各种附属可执行文件进行一些重写。我们开发了一个新的 API 来解决我们的基础类也存在一些令人烦恼的问题。到目前为止,这是一个正常的,尽管影响广泛的更新。

我们的层次结构是:

  1. ASP.NET (aspx)
  2. 业务逻辑 (DLL)
  3. 基础类 (DLL)

所以 ASP.NET 不适合,一些 DLL(特别是基础类)有一个重定向层,其中包含旧的命名空间/函数并将它们转发到新的 API。当我们替换 DLL 时,ASP.NET 很好地选择了它们(可能是因为它触发了重新编译)。

但预编译的应用程序不会,即使相同的命名空间和类位于两组 DLL 中。即使文件被重命名,它也会抱怨 assemblyname 属性不同(必须如此)。我知道你可以重定向到同一个程序集的不同版本,但是有什么方法可以重定向到完全不同的程序集?

替代方法是重新编译应用程序(不要真的想要,因为应用程序本身没有更改)或使用引用新基础 DLL 的存根重新编译旧的基础 DLL(新的虚拟 DLL 是文件系统混乱) .

【问题讨论】:

    标签: c# .net assemblies resolve


    【解决方案1】:

    您想将类型移动到新程序集中吗?你可以通过[TypeForwardedTo(..)] 做到这一点。

    如果您原来有 (AssemblyA):

    namespace SomeNamespace {
        public class SomeType {}
    }
    

    您可以改为将该类型移动到AssemblyB,并拥有一个实际上是空的AssemblyA,它引用AssemblyB,并且只包含:

    [assembly: TypeForwardedTo(typeof(SomeNamespace.SomeType))]
    

    然后任何试图从AssemblyA 加载SomeNamespace.SomeType 的东西实际上AssemblyB 获取类型。

    大多数运行时都尊重此属性...除了 WCF 扩展之外的所有内容。哪个咬我;-p 哦,它不喜欢嵌套类型...

    【讨论】:

    • 我希望摆脱对原始应用程序或旧 API 库的困扰。虽然 TypeForwarder 是一个有趣的概念,但在这种情况下它不起作用。 RK1.DLL 有 RK1.API.FUNCTION()。 RK2.DLL 有 RK2.API.Function() 和 RK1.API1.FUNCTION() 转发回 RK2.API2.Function()。正因为如此,RK1.DLL 和 RK2.DLL 不能被同一个应用程序调用,我认为如果我试图将一个类型转发给它认为是它自己的类型,编译器会出错。我只是想要一种方法将 RK2.DLL 放入其中,将 RK1.DLL 重命名为 RK1.notaDLL,然后让应用程序正常工作。
    • 我很惊讶该框架支持在运行时强制应用程序按版本重定向,但没有办法(我发现)在不重新编译的情况下转发到另一个程序集。
    • @RK - 在黑暗中盲目射击;你试过AppDomain.CurrentDomain.AssemblyResolve吗?如果找不到第一个程序集,您可以处理此问题并返回新程序集(通过Assembly.Load(newName)...
    • 是的,我确实找到了那个选项,但它似乎仍然需要重新编译调用者应用程序。如果我还是要重新编译应用程序,我不妨将引用指向正确的文件。
    • 现在第一次调查类型转发 - 您可以在没有从 AssemblyA 到 AssemblyB 的情况下执行此操作吗?我正在尝试在相反方向已经存在依赖的情况下执行此操作:(
    【解决方案2】:
    //File: RKAPPLET.EXE
    namespace RKAPPLET
    {
      using RKMFC;
      public static class Program
      {
        public static void Main ()
        {
          RKMFC.API.DoSomething();
        }
      }
    }
    
    //File: RKMFC.DLL
    namespace RKMFC
    {
      public static class API
      {
        public static void DoSomething ()
        {
          System.Windows.Forms.MessageBox.Show("MFC!")
        }
      }
    }
    
    //File: RKNET.DLL
    namespace RKNET
    {
      public static class API
      {
        public static void DoSomethingElse ()
        {
          System.Windows.Forms.MessageBox.Show("NET!")
        }
      }
    }
    namespace RKMFC
    {
      public static class API
      {
        public static void DoSomething ()
        {
          RKNET.API.DoSomethingElse()
        }
      }
    }
    

    我希望用 RKMFC.DLL 编译的 RKAPPLET.EXE 找到 RKNET.DLL(它具有 RKMFC.DLL 中所有内容的副本,然后是一些),而无需重新编译 RKAPPLET.EXE(指向它)或 RKMFC。 DLL(重定向类型)。

    【讨论】:

      【解决方案3】:

      您是否尝试将<assemblyBinding> 设置添加到配置文件?

      http://msdn.microsoft.com/en-us/library/twy1dw1e.aspx

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-01
        • 2011-04-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多