【问题标题】:I want my DotNetNuke modules to work under as many versions as possible while avoiding assembly binding redirection我希望我的 DotNetNuke 模块在尽可能多的版本下工作,同时避免程序集绑定重定向
【发布时间】:2025-12-15 19:45:01
【问题描述】:

我正在开发 DotNetNuke 模块,自然希望在安装或分发它们之前对其进行编译。过去,我只是通过浏览到本地 DotNetNuke 安装的 /BIN 文件夹来引用特定版本的 DotNetNuke.dll。

这个参考允许我使用 DNN 基类并在这些基础上创建我自己的一组类。我还在我需要的整个 DNN 命名空间/类中使用了各种辅助方法。 (即从它们的 PortalModuleBase、ModuleSettingsBase 创建派生类,并使用它们的本地化类来替换 Microsoft 的 ASP.NET 实现提供的那些。)

我已经能够摆脱这种直接引用 DLL 的方法(复制本地 = True,特定版本 = False),因为直到现在我一直将这些模块安装到我维护的客户端网站上。因此,我至少将它们保留在我一直在开发的 DotNetNuke 版本或更新版本上。最近,我在开发中引用了 6.1.3.108。

注意:这会自动将以下关联的 DLL 复制到我的模块的 /BIN 目录中:

  • DotNetNuke.dll
  • DotNetNuke.Instrumentation.dll
  • dotnetnuke.log4net.dll
  • DotNetNuke.Services.Syndication.dll
  • DotNetNuke.Web.Client.dll
  • DotNetNuke.WebControls.dll
  • DotNetNuke.WebUtility.dll

将它安装到较新版本的 DotNetNuke 站点上运行良好,这不是一个糟糕的开始。

我一直想知道的是,是否有一种非骇客的方法可以使我的模块对 DLL 的次要、构建或修订级别不敏感?

我意识到我有责任确保产品(如果在“中端”版本上开发)仍然适用于稍早版本的产品以及更新版本的产品。也就是说,我觉得我可以对这些构建进行彻底的测试。对我来说,这比在开发中运行 OLDEST 主要构建更重要。

换句话说,我宁愿不参考 6.0.0.0 进行开发,这样它就可以在 6.x.x.x 上运行而无需额外的努力。如果有人没有让我参考的绝妙方法,我只会这样做,比如 6.1.3.108 工作在稍早或更高的版本上。 (当然,我可以为主要版本更改制作不同的模块,例如 5.x.x.x 或 7.x.x.x。)

提前致谢!

【问题讨论】:

    标签: assemblies dotnetnuke versioning dotnetnuke-module


    【解决方案1】:

    不要在 bin 文件夹中引用程序集,而是在源代码中保留一份 DotNetNuke.dll(以及任何其他引用),并在那里引用它。将支持的最旧版本放在那里,但在较新的站点上开发。在引用上设置 Copy Local=False,这样您就不会覆盖较新的版本,应该没问题。

    通过这种方式,我们能够在开发在 DNN 6.1.x 上运行的模块时引用 DNN 4.5.3。我多年来一直在使用这种方法,没有出现任何重大问题(除了我偶尔忘记关闭 Copy Local 并且我的 DNN 网站神秘地崩溃了)。

    【讨论】:

    • 这就是我的开发方式。支持多种版本没有灵丹妙药。 OP中描述的方式是我推荐的。如果需要,创建您自己的扩展子类,并在这些子类中实现反射。
    • 很酷的东西,当我从回答我的问题的人那里购买/推荐模块时,你知道这是一个紧密的社区。感谢 Engage 和 iFinity! @BruceChapman - 您能否详细说明如何使用扩展子类和反射。我已经扩展了关键模块和模块设置类。但是说我使用反射来确定加载的 DotNetNuke 版本,我该如何利用它? (也许将其添加为另一个答案,这样我至少可以为您提供帮助。)
    【解决方案2】:

    关于在您从 DNN 子类化的类中确定 DNN 的版本。

    这就是我要做的,假设 YourClass 继承自 DNNClass,但是因为您引用了早期版本的属性,所以“NewProp”不存在。操作方法如下:

    public class YourClass : DNNClass
    {    
        public string NewPropSubstitute
        {
           get {
    
               string newPropVal = "your default if earlier DNN";
               System.Reflection.PropertyInfo pi = this.GetType().GetProperty("NewProp");
               if (pi != null)
                   newPropVal = (string)pi.GetValue(this, null);
               return newPropVal;
           }
        }
    }
    

    这是凭记忆猜测的,所以它可能无法编译,但你明白了。如果您愿意,您不一定非要获取 DNN 版本 - 只需尝试通过反射获取属性 - 如果它存在,则暗示您已经获得了正确的版本。

    当然,如果 DNN 版本不支持,此方法假定您可以用一个值替换后来的 DNN 属性(或方法)。但这一切都取决于你想要做什么。

    如果您确实想找到 DNN 版本(版本安全且始终正确),您可以使用嵌入在我的版本安全的 jQuery 包含代码中的代码,链接自此博客文章: Using jQuery in DotNetNuke 5 and 6

    【讨论】:

    • 感谢 Bruce,我实际上已经阅读了您的 jQuery 方法。我经常不喜欢编写代码来“如果这个,那么做,否则如果这个,那么做,否则如果,等等”。但绝对公平地说,我没有想到任何解决方法!因此,除非 JavaScript 不再是“脚本式”,否则它将是我们所拥有的一切。再次感谢! (顺便说一句:当我和你聊天时,我忍不住想念澳大利亚。几年前我在那里住了一年多。希望去年夏天天气不太干燥,你的足球队正在获胜。去科林伍德!)跨度>
    最近更新 更多