> 技术文档 > 精通微软 Dynamic365(一)

精通微软 Dynamic365(一)


原文:annas-archive.org/md5/4b7740950c4db25f9fa2b4a0e4722a06

译者:飞龙

协议:CC BY-NC-SA 4.0

序言

本书适用于需要在 Microsoft Dynamics 企业资源规划ERP)之上创建应用程序和定制的 Dynamics 365 Business Central 开发人员。

本书首先解释了 Microsoft Dynamics 365 Business Central 平台(重点介绍软件即服务SaaS)平台)以及现代开发环境(Visual Studio Code、AL 语言和其他工具,如 Docker)。然后,本书涵盖了所有开发者需要了解的扩展和自定义 ERP 的主题,重点是如何编写更好的代码,遵循最佳实践,如何调试和部署扩展,以及如何编写自动化测试。

本书还涵盖了与集成、云服务和无服务器处理相关的高级主题(包括使用 Dynamics 365 Business Central 与 Office 365 应用程序,如 Power BI、Flow 和 PowerApps 的集成;与机器学习功能的集成;以及如何将 DevOps 技术应用到开发过程中)。

本书的最后一个主题是架构,分析了将现有解决方案迁移到基于扩展的新开发模型的最佳方法。

本书的读者对象

本书面向具有业务流程和 C/AL 编程高级知识的 Microsoft Dynamics NAV/Dynamics 365 Business Central 开发人员和解决方案架构师。了解 Web 服务编程(API)和 C# 会是加分项。

本书涵盖的内容

第一章,Microsoft Dynamics 365 Business Central 概述,提供了 Dynamics 365 Business Central 架构(云端和本地)的技术介绍,并介绍了新的开发平台。

第二章,掌握现代开发环境,概述了适用于 Dynamics 365 Business Central 的现代开发环境,并提供了如何在开发扩展时高效使用 Visual Studio Code 的技巧和窍门。

第三章,基于在线和容器的沙盒,详细介绍了如何为开发创建 Dynamics 365 Business Central 沙盒环境,如何使用在线沙盒进行测试,以及如何使用 Docker 改善开发过程。

第四章,扩展开发基础,提供了新的扩展模型的概述,解释了与过去的不同、新的对象类型,以及如何使用 AL 创建对象。

第五章,为 Dynamics 365 Business Central 开发定制化解决方案,指导你使用 Visual Studio Code 和 AL 语言从实际业务案例出发,开发完整的 Dynamics 365 Business Central 解决方案。在本章中,你将看到如何创建一个完整的解决方案,以及如何为客户定制解决方案,而不修改基础代码。

第六章,高级 AL 开发,讲解了开发扩展时需要了解的高级编程主题,如文件管理、使用.NET 对象、使用 AL 调用 Web 服务、处理 XML 和 JSON、处理媒体文件、处理通知、异步编程等。

第七章,使用 AL 进行报表开发,介绍了如何在新的扩展模型中处理报表(新报表的创建和现有报表的定制)。

第八章,安装和升级扩展,教你如何处理 Dynamics 365 Business Central 扩展的安装和升级逻辑。

第九章,调试,教你如何调试扩展以及如何检查代码和变量。

第十章,使用 AL 进行自动化测试开发,详细介绍了如何为 Dynamics 365 Business Central 扩展编写和执行自动化测试。

第十一章,与 Business Central 的源代码管理和 DevOps,讲解了在为 Dynamics 365 Business Central 开发解决方案时,如何高效地处理源代码管理技术,并概述了如何处理持续集成/持续交付CI/CD)和 DevOps 技术,适用于你的扩展项目。

第十二章,Dynamics 365 Business Central API,介绍了 Dynamics 365 Business Central 的 API 框架。它展示了如何使用现有的 API,如何创建新的 API 来扩展平台,以及一些高级 API 主题,如绑定操作和 Webhooks。

第十三章,使用 Business Central 和 Azure 实现无服务器业务流程,描述了如何将 Azure Functions 与 Dynamics 365 Business Central 结合使用,在云中执行.NET 代码并实现无服务器处理解决方案。

第十四章,使用 Azure Functions 进行监控、扩展和 CI/CD,教你如何监控 Azure Functions,如何处理可扩展性以提高性能,以及如何使用 Azure DevOps 实现 CI/CD 过程。

第十五章,Business Central 与 Power Platform 的集成,展示了将 Dynamics 365 Business Central 与 Dynamics 365 Power Platform 结合使用的方式。我们将概览 Power Platform 应用,并通过与 Dynamics 365 Business Central 配合使用 Power Platform 的一些实际应用。

第十六章,将机器学习集成到 Dynamics 365 Business Central,概述了如何将机器学习功能集成到 Dynamics 365 Business Central 扩展中。

第十七章,将现有 ISV 解决方案迁移到新的扩展模型,讲解了如何将一个现有的 ISV 解决方案(使用旧的 C/AL 代码编写)迁移到新的扩展模型。内容详细讲解了架构方面的内容,并提供了如何正确开始该过程的建议。

第十八章,AL 开发者的实用工具,介绍了一些对开发经验非常有帮助的第三方工具。

获取本书最大收益

你应该熟悉使用 C/AL 编程语言进行 Dynamics NAV 或 Dynamics 365 Business Central 的开发,并且能够使用 PowerShell 和 Azure 门户等工具。了解云计算概念将大大帮助你理解某些话题。

本书将指导你如何创建完整的解决方案并解决任务。如果你希望从本书中获得最大收益,至少在试用环境中跟随提供的示例进行操作是必须的。

下载示例代码文件

你可以从你的帐户在 www.packt.com 下载本书的示例代码文件。如果你是从其他地方购买本书的,可以访问 www.packtpub.com/support 注册并让我们直接通过电子邮件将文件发送给你。

你可以按照以下步骤下载代码文件:

  1. 登录或注册到 www.packt.com。

  2. 选择 Support 标签。

  3. 点击 Code Downloads。

  4. 在 Search 框中输入书名并按照屏幕上的指示操作。

下载文件后,请确保使用最新版本的解压工具解压文件夹:

  • Windows 版的 WinRAR/7-Zip

  • Zipeg/iZip/UnRarX for Mac

  • Linux 版的 7-Zip/PeaZip

本书的代码包也托管在 GitHub 上,地址是 github.com/PacktPublishing/Mastering-Microsoft-Dynamics-365-Business-Central。如果代码有更新,将会在现有的 GitHub 仓库中进行更新。

我们还有来自丰富书籍和视频目录的其他代码包,可以在 github.com/PacktPublishing/ 查找。快去看看吧!

下载彩色图片

我们还提供一份包含本书中使用的截图/图表的彩色图像的 PDF 文件,您可以在这里下载:static.packt-cdn.com/downloads/9781789951257_ColorImages.pdf

使用的约定

本书中使用了多种文本约定。

CodeInText:表示文本中的代码词语、数据库表名、文件夹名、文件名、文件扩展名、路径名、虚拟网址、用户输入和 Twitter 账户名。举个例子:“这是一个 docker run 命令的输出,其中该镜像在本地不可用。”

一段代码如下所示:

mcr.microsoft.com/businesscentral/onprem:1910-cu1-au-ltsc2019

所有命令行输入或输出都以以下方式书写:

docker network create -d transparent transpNet

粗体:表示新术语、重要单词或屏幕上出现的词语。例如,菜单或对话框中的词语在文本中是这样显示的。举个例子:“只需浏览 dynamics.microsoft.com/en-us/business-central/overview/,然后在所需的许可模块下点击 ‘Find a partner’。”

警告或重要提示以此方式出现。

提示和技巧以此方式出现。

与我们联系

我们始终欢迎读者的反馈。

一般反馈:如果您对本书的任何部分有疑问,请在邮件主题中提及书名,并通过customercare@packtpub.com与我们联系。

勘误表:虽然我们已尽力确保内容的准确性,但错误难免。如果您在本书中发现错误,我们将非常感激您能向我们报告。请访问 www.packt.com/submit-errata,选择您的书籍,点击 “Errata 提交表单” 链接,并输入详细信息。

盗版:如果您在互联网上发现任何形式的非法复制我们作品的情况,我们将非常感激您能提供相关网址或网站名称。请通过 copyright@packt.com 联系我们并附上相关内容的链接。

如果您有兴趣成为作者:如果您在某个领域有专业知识,并且有兴趣写书或为书籍做贡献,请访问 authors.packtpub.com。

评论

请留下评论。阅读并使用本书后,为什么不在您购买书籍的网站上留下评论呢?潜在读者可以通过您的公正意见做出购买决策,我们可以了解您对我们产品的看法,作者也能看到您对其书籍的反馈。谢谢!

欲了解更多关于 Packt 的信息,请访问 packt.com。

第一部分:Dynamics 365 Business Central - 平台概述与现代开发基础

在本节中,我们将介绍 Dynamics 365 Business Central 的架构(云端与本地部署)以及新的开发平台。

本节包含以下章节:

  • 第一章,Microsoft Dynamics 365 Business Central 概述

  • 第二章,掌握现代开发环境

  • 第三章,在线与基于容器的沙盒

第一章:Microsoft Dynamics 365 Business Central 概述

Microsoft Dynamics 365 Business Central 是一款顶尖的基于云的 企业资源规划ERP)应用软件,专为 中小企业SMB)市场设计。该应用基于 软件即服务SaaS)模式,并通过 云解决方案提供商CSP)合作伙伴进行销售。

潜在客户可以随时启动试用租户,或联系 CSP 合作伙伴购买并分配按用户计费的许可。

本章将涵盖以下主题:

  • 客户视角:什么是 Dynamics 365 Business Central,涵盖了哪些功能领域,以及许可方式

  • 合作伙伴视角:Business Central 管理中心概述及其使用

  • Microsoft 视角:深入了解 Microsoft Dynamics 365 Business Central 的技术细节

  • 未来视角:未来几年可能会发生的变化以及如何为实现这些变化做出贡献

到本章结束时,你将对 Microsoft Dynamics 365 Business Central 平台有一个清晰而深入的概述。

理解客户视角

针对中小企业,Dynamics 365 Business Central 的核心设计依赖于 Microsoft Azure 和 Office 365 平台。该应用的核心代码和业务流程来源于 Microsoft Dynamics NAV(通常称为 Navision)30 多年来功能增强的演变:这是中小企业领域最坚固的本地部署 ERP 软件之一。

潜在客户——或者那些只是想体验一下该应用的人——可以通过 trials.dynamics.com/Dynamics365/Signup/BusinessCentral 提供与 Office 365 订阅绑定的电子邮件地址和电话号码,快速设置并试用该产品。30 天试用期结束后,产品需要购买。

正式授权仅通过经过 CSP 项目认证的 Microsoft 合作伙伴分配。只需浏览 dynamics.microsoft.com/en-us/business-central/overview/ 并在所需的许可模块下点击“查找合作伙伴”,如以下截图所示:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/ms-ms-dyna365/img/90336d57-47ec-475d-8175-086c58abdc87.png

Microsoft Dynamics 365 Business Central 提供开箱即用的功能模块,按每个用户每月固定价格收费。根据不同的功能和应用模块,有三种按用户/每月计费的选择:Essentials(基础版)、Premium(高级版)和 Team Members(团队成员)。Essentials 和 Premium 是完整用户,而 Team Members 只是具有有限功能的额外用户。

以下是 Essentials 模块的属性(功能集合)(从每月 $70 起):

  • 财务管理

  • 客户关系管理

  • 项目管理

  • 供应链管理

  • 人力资源管理

  • 仓库管理

这些是 Premium 模块的属性(每月起价 100 美元):

  • 财务管理

  • 客户关系管理

  • 项目管理

  • 供应链管理

  • 人力资源管理

  • 仓库管理

  • 服务管理

  • 制造业

当前,在同一租户中不可能拥有 Essential 和 Premium 混合的用户体验。可以从 Essential 模块升级到 Premium 模块,但不能从 Premium 降级到 Essential。如果你已经至少有一个用户被授权为 Essential 或 Premium,那么可以将外部用户作为命名许可的 Team Member 添加到相同的模块(Essential 或 Premium)中。

这就是作为 Team Member 获得的内容(每月起价 8 美元):

  • Essential 或 Premium(取决于添加团队成员的用户模块)。

  • 消耗数据或报告的能力、完成轻任务(如时间或费用条目及人力资源记录更新),并使用 PowerApps for Dynamics 365。

  • 从技术上讲,他们可能对所有表格具有读取权限,但只能对最多三张表具有插入/更新权限。

有关许可类型及其包含内容的所有详细信息已在官方 Microsoft Dynamics 365 Business Central 许可指南中描述(截至写作时的最新审查为 2019 年 10 月),可通过以下链接找到:mbs.microsoft.com/Files/public/365/Dynamics365BusinessCentralLicensingGuide.pdf

一旦客户开始使用他们的试用版或生产版租户,他们将获得一个富有生产力、直观且用户友好的 Web 客户端界面,如下图所示:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/ms-ms-dyna365/img/f1c17d82-5a33-4c3c-b0bf-eaf95a37ecb5.png

最佳的浏览器体验由 Microsoft Edge 或 Google Chrome 提供。

客户还可以在几乎所有现代设备上受益于通用应用程序部署类型,如平板电脑、智能手机和手机。这是通过从 Windows Store、Google Play 或 Apple Store 下载名为 Dynamics 365 Business Central Universal App 的应用程序实现的。要安装移动应用程序,请访问 docs.microsoft.com/en-us/dynamics365/business-central/install-mobile-app

打开此网站后,我们会看到安装移动应用程序的三个选项。您可以从 Microsoft 安装、从 Apple Store 下载,或从 Google Play Store 获取。以下是选择从 Microsoft 安装应用程序时您将看到的屏幕截图片段:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/ms-ms-dyna365/img/9019c817-d57d-4f60-9e82-3a633d45ac99.png

截至写作时,Microsoft Dynamics 365 Business Central 已在 18 个国家/地区(按发布日期排序)由微软正式本地化并发布:

2018 年 4 月 2018 年 7 月 2018 年 10 月 美国 澳大利亚 墨西哥 加拿大 新西兰 挪威 英国 冰岛 丹麦 荷兰 德国 西班牙 意大利 法国 奥地利 瑞士 比利时 瑞典 芬兰

从 2018 年 10 月更新开始,CSP 合作伙伴现在可以为 Dynamics 365 Business Central 尚未发布或尚未成为微软本地化目标的国家创建自己的本地化版本。

这些本地化版本以全球标准应用基础(称为 W1)为起点,并通过 Microsoft Dynamics 365 Marketplace 分发,称为 AppSource。像通过 AppSource 部署的任何扩展(或应用程序)一样,所有的应用程序和技术支持由通过 AppSource 销售该应用程序的合作伙伴提供。

你可以在docs.microsoft.com/en-us/dynamics365/business-central/dev-itpro/developer/readiness/readiness-develop-localization#service-availability-in-additional-countries查看更多内容。

以下是当前额外的 CSP 本地化国家(截至写作时)的应用程序和发布者名称列表:

爱沙尼亚 爱沙尼亚语包 爱沙尼亚增值税报告本地化 爱沙尼亚企业登记本地化 爱沙尼亚银行格式本地化 爱沙尼亚 Intrastat 报告本地化 Estonian Dynamics Partners 香港特别行政区 香港繁体中文语言包 香港繁体中文包 香港繁体中文语言 Tectura Hong Kong LimitedPacific Business Consulting, Inc.K-Solve IT Solutions Limited 印尼 印度尼西亚税务计算本地化 Wahana Ciptasinatria 日本 日本语包 J-Pack – 日本本地化 Pacific Business Consulting, Inc. 马来西亚 ADS 报告(入门)本地化 ADS 本地税(入门)本地化 ADS Global SSO Sdn Bhd 波兰 波兰语包 波兰功能性–入门包 IT.integro sp. z o.o. 葡萄牙 SOFTSTORE 本地化语言包 SOFTSTORE 本地化包 Softstore SA 塞尔维亚 塞尔维亚语包 塞尔维亚本地化 Adacta d.o.o. 新加坡 新加坡本地化 AFON GST 本地化 新加坡 Dalstech GST 本地化 IBIZ Consulting Pte LtdAFON Systems Pte LtdDalstech Pte Ltd 南非 南非发票 Braintree by Vox 韩国 韩国语包 韩国增值税本地化 DEEX Korea Co LtdMAVEN Korea Co., Ltd. 台湾 台湾繁体中文语言包政府统一发票GUI)台湾 台湾工资系统 Knowledge & Strategy Information Co., Ltd. 泰国 泰国增值税(VAT)和预扣税(WHT)本地化 Triple P Application Co., Ltd.、AVISIONTHU、biz Solution Co., Ltd. 阿联酋 阿联酋增值税本地化 Alfazance Consulting

你可以在docs.microsoft.com/en-us/dynamics365/business-central/dev-itpro/compliance/apptest-countries-and-translationsappsource.microsoft.com/en-us/marketplace/apps?product=dynamics-365%3Bdynamics-365-business-central&page=1上阅读更多相关信息。

现在我们了解了 Dynamics 365 Business Central 是什么以及它为客户提供什么,让我们深入探讨一下合作伙伴的视角。

理解合作伙伴的视角

CSP 使合作伙伴能够访问一系列可销售的 Microsoft 云服务。在此计划中,提供了一些管理和支持这些云服务的工具。其中一项在线服务是 Dynamics 365 Business Central。

你可以在docs.microsoft.com/en-us/partner-center/csp-overview上了解更多有关合作伙伴中心的信息。

在 SaaS 提议中,潜在客户只能通过 CSP 合作伙伴或其经销商购买 Dynamics 365 Business Central 的许可证,并将试用许可证转换为按使用付费的许可证,或直接支付用户的月费。

在每个 CSP 中,合作伙伴或经销商在Azure Active DirectoryAAD)中由唯一的租户记录表示。AAD 是一个多租户身份验证服务,提供身份和访问功能,适用于在 Microsoft Azure 和 Microsoft 本地环境中运行的应用程序。

在此特定的 AAD 租户记录中,合作伙伴可以定义不同类型或类别的用户(通常称为支持代理),这些用户主要分为两个不同的组(即所谓的代理组):管理员帮助台组。

与合作伙伴类似,客户也有自己独特的 AAD 租户记录。当在 Dynamics 365 Business Central 租户中订阅 Essential 或 Premium 计划时,每个客户都同意 CSP 合作伙伴与客户 AAD 租户之间建立特殊的信任关系。

关系的方向是从客户租户到合作伙伴租户,如果需要,可以由客户撤销和/或管理。

在客户的 AAD 租户中,定义并管理用户、角色和订阅实体。角色由客户分配给用户,这些角色反映了他们在订阅的产品中的能力。要在客户 AAD 租户中订阅 Dynamics 365 Business Central 等在线产品,CSP 合作伙伴还需要将特定的在线产品许可证分配给用户。

这些任务通过Business Central 管理门户执行。客户或 CSP 合作伙伴都可以直接访问该门户。CSP 合作伙伴也可以通过Partner Center门户访问:

  1. 使用 Partner Center 门户,有几种方式可以浏览到 Dynamics 365 Business Central 管理中心门户。其中一种方式是通过“服务管理”选项卡。服务管理选项卡包含指向与特定客户 AAD 租户相关的各种管理门户的链接,例如 Exchange 或 Office 365。它还显示产品的服务健康状态,这些产品与门户或管理员控制台相关联,例如 Exchange Online、身份服务和 Dynamics 365 Business Central。

  2. 通过点击 Dynamics 365 Business Central 链接,合作伙伴将被直接重定向到 Dynamics 365 Business Central 管理中心门户。在合作伙伴中心门户中,CSP 合作伙伴还可以查看客户的订单历史记录,并查看他们所属的订阅内容。还可以选择 Dynamics 365 Business Central 的计费频率——例如按月或每年一次——并代表该客户订阅不同的在线服务。

  3. 订阅按提供类型(级别)进行划分。例如,在 Dynamics 365 Business Central 中,可以选择 Essential 或 Premium 计划。

  4. 在“用户和许可证”部分,CSP 合作伙伴可以手动添加用户或从文件中批量上传用户。对于每个用户,可以分配不同的服务许可证。

  5. 一旦分配了许可证,用户就可以开始使用 Dynamics 365 Business Central,并且该应用将出现在他们的首页 home.dynamics.com 上。点击 Dynamics 365 Business Central 图标会将用户重定向到第一次登录页面,他们可以立即在生产租户中开始工作。你可能会注意到,URL 的定义通过易于识别的固定客户端端点和客户租户带来了好处,且其 Dynamics 365 Business Central 管理门户应如下所示:

    • 客户租户:businesscentral.dynamics.com/

    • 客户租户管理门户:businesscentral.dynamics.com//admin

GUID 标识了你在 Partner Center 门户中所在的相同客户环境。

自 2019 年秋季更新以来,如果您有多个生产环境,当您点击首页上的 Dynamics 365 Business Central 图标(home.dynamics.com)时,系统会提示您选择要选择的环境名称。环境端点应如下所示:businesscentral.dynamics.com/

那么,谁可以访问 Dynamics 365 Business Central 管理中心门户?答案如下:

  • 拥有与客户租户的有效授权关系的 CSP 合作伙伴管理员和帮助台代理

  • 客户的 AAD 全局管理员

拥有 Dynamics 365 Business Central 许可的用户将无法访问管理门户。产品许可证与 Dynamics 365 Business Central 管理中心门户访问之间没有关系。

客户的 AAD 租户全局管理员可以登录,而合作伙伴 AAD 租户管理员和帮助台用户可以作为委托管理员访问。委托管理员可以作为合作伙伴执行提升的任务,但他们没有客户全局管理员的相同权限。简而言之,委托管理员不是租户的全局管理员。

Dynamics 365 Business Central 管理中心门户示例

以一个快速示例来说,委托管理员不能在客户租户中创建新公司,而应当请客户管理员(拥有超级权限)创建新公司,或由客户提升权限,以便添加适当的 Dynamics 365 Business Central 权限。一旦新公司创建完成,委托管理员可以登录并执行他们有权进行的管理任务。

合作伙伴委托管理员可以通过输入 Dynamics 365 Business Central 固定端点,businesscentral.dynamics.com,然后输入客户租户的 AAD 名称(例如,businesscentral.dynamics.com/customerAADtenantname.onmicrosoft.com),来登录与其有关系的特定客户租户。这是必要的,因为合作伙伴可能需要处理多个客户的管理任务,并且在日常活动中可能需要快速连接、断开连接和重新连接。

Dynamics 365 Business Central 管理中心门户目前包含四个部分(环境通知接收者遥测和报告的故障),如下面截图中侧边栏所示:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/ms-ms-dyna365/img/44e1ae40-fd0e-4389-b7f0-36a296be1434.png

我们将在接下来的部分中逐一讲解这些内容。

环境

环境列出了特定客户的所有 Dynamics 365 Business Central 生产和沙箱租户。对于每个租户,展示了其状态、供应国家、版本和升级窗口。

截至写作时,可用的操作如下:

  • 新建。创建新的生产环境或沙盒租户。目前,最多可以为相同或不同国家创建三个生产租户,以及最多三个沙盒租户。可以将沙盒作为生产数据库的副本进行创建。

    根据生产租户中的数据量,从生产租户创建沙盒的操作可能需要较长时间。

  • 删除。您可以选择删除一个沙盒或生产租户。

截至写作时,特定租户的可用操作如下:

  • 设置更新窗口。为特定租户配置一个本地时间的更新窗口。更新窗口允许您选择开始时间和结束时间。更新完成后,微软会发送通知。该通知通常包含更新是否成功执行的详细信息,如果失败,则会说明失败的原因。如果更新失败,通知中将添加一份可操作的故障报告,供合作伙伴和/或客户采取相应措施。

  • 安排更新。当有新更新时,微软会向管理员中心接收者发送通知,通过此操作,可以安排更新。

  • 删除。删除当前的生产环境或沙盒租户。

  • 报告生产环境故障。这是自 2019 年秋季更新以来的新功能。如果用户无法连接到生产环境,只需按下生产故障按钮,即可提交记录(工单)请求,向 Dynamics 365 Business Central 运营中心寻求即时帮助。该工单将被优先处理,以便及时解决问题。

  • 管理支持联系人。用于为特定环境添加支持联系人。用户将在 Business Central 帮助与支持页面上看到此信息。可以为每个租户选择不同的支持联系人,或选择一个适用于所有租户的联系人。

由于微软不断添加新操作,已宣布以下功能将在 2019 年 10 月正式发布后推出:

  • 能够下载生产租户的 Azure SQL 备份(BACPAC)。可以将其还原到本地,以便进行离线故障排除、数据分析以及商业智能BI)驱动的任务。

欲了解更多信息,请访问 docs.microsoft.com/en-us/dynamics365-release-plan/2019wave2/dynamics365-business-central/planned-features

通知接收者

通知接收人列出了特定客户的所有 Dynamics 365 Business Central 通知接收人。该列表显示接收人的姓名和电子邮件地址。当某个生命周期任务完成时,这些用户将收到通知,例如,当应用了小更新或有新版本的应用程序升级时。

如果希望开发人员和测试人员在某些事情发生或即将发生时得到通知,以便有足够的时间审查他们的自定义开发与新的标准应用程序代码的匹配情况,这个功能会非常有用。

遥测

这显示了一个过滤面板,包含特定客户的日期、时间和事件类型。

可以设置过滤器来指定特定环境(生产或沙箱),并通过指定回溯的分钟数来回溯到过去。该列表报告以下内容:

  • 时间戳:表示操作何时被记录的值。

  • 级别:一个整数值,表示错误、警告和信息。

  • 操作码名称:应用程序操作类型(例如,启动或停止)。

  • 对象类型和 ID:表示生成日志的对象类型和 ID。

  • 对象扩展名称和 ID:如果没有显示任何值,表示遥测日志直接来自遗留应用程序代码(C/AL)。

  • 功能名称:表示生成日志的对象功能名称。

  • 失败信息:如果没有显示任何值,通常表示这是关于某个特定对象功能的启动或停止操作的信息消息。

对于指定的时间范围,还可以在列中搜索特定操作或错误消息。这通常用于沙箱或预发布环境,以查找标准基础应用程序与已开发的自定义扩展之间是否存在不一致或运行时错误。

报告的生产中断

这是 2019 年秋季更新中的新功能。它报告了生产中断票据及其状态。可以过滤显示过去 30 天、14 天或 7 天内的记录。

更多信息可以在 docs.microsoft.com/en-us/dynamics365/business-central/dev-itpro/administration/tenant-admin-center 查阅。

除了通过门户的用户界面UI)登录客户端并执行操作外,合作伙伴中心和 Dynamics 365 Business Central 管理门户还提供了一组强大的 API,可以用来创建一个自定义外观,以现代化、完全自动化的方式处理客户创建、许可证分配及其他任务。

即使对 PowerShell 或 Visual C# 有基本了解,并且没有高级开发技能,仍然可以迈出创建自定义仪表板的第一步,并自动化创建新客户用户、分配或撤销许可证等操作。

例如,我们可以使用以下端点:api.businesscentral.dynamics.com/v1.2/admin/applications/BusinessCentral/environments/Sandbox

它是如何在幕后工作的

固定的 Web 服务端点全局服务被调用,并将信息重定向到全局租户管理器全球服务,该服务会执行广播操作并确定请求属于哪个区域控制平面、数据平面和租户。

在检索所需信息后,固定的 Web 服务端点会直接将请求来回传递到所选的区域控制平面。换句话说,全球服务仅执行了第一次路由信息任务(一个简单的代理任务)。

当固定的 Web 服务端点被路由到与特定区域控制平面通信时,它将开始与租户管理员后台服务进行交互。

您可以在docs.microsoft.com/en-us/partner-center/develop/docs.microsoft.com/en-us/dynamics365/business-central/dev-itpro/administration/administration-center-api上了解更多信息。

在撰写本文时,一些合作伙伴已经在他们的项目中实现了 Dynamics 365 Partner Center SDK,并在 Dynamics 365 Business Central 本地环境中(使用 .NET 互操作性)消费这些 API,以实现一个完全集成的客户租户管理仪表板。这也可以用于演示目的。

现在我们已经释放了一些微软为其合作伙伴提供的最佳功能,接下来让我们来看看 Dynamics 365 Business Central 背后的运作方式。

Dynamics 365 Business Central 的幕后运作

微软在去年进行了大量投资,并继续投资于现代化和精简化的 Dynamics 365 Business Central 架构,以便拥有一个易于部署和升级的 ERP 云服务解决方案。

在撰写本文时,统计数据非常鼓舞人心,甚至超出了预期。

基本上,每 180 秒就会创建一个新的 Dynamics 365 Business Central 租户。每分钟会产生 400,000 个度量数据,约有 8 TB 的日志每天生成。这些日志随后会被预处理、聚合,并有大约 4 TB 的数据通过 Azure Data Lake 服务上传到 Cosmos DB 进行大数据分析。

这些只是 Dynamics 365 Business Central 所产生的一些数据,和一些用于提供世界上最佳在线 ERP 体验的 Microsoft 云服务。

以目前的进展来看,在不久的未来,人工智能AI)可能会在所有平台和应用程序级别上自发触发微服务调整。

更深入地考虑,由于涉及到 Azure 技术,截至撰写本文时,每个微服务集合中协调的资源总共有 20 个。这显示了向用户和开发者提供的复杂环境是如何以最简化的方式呈现的。

Dynamics 365 Business Central 开发团队的主要目标是将可扩展性负担转移给合作伙伴和客户。合作伙伴和客户无需再关注数据存储的位置和方式,也不需要关心用于收集、转换和升级数据的技术。相反,他们应该专注于扩展应用程序。无需平台技能;只需点击刷新并重复“开发者,开发者,开发者……”。

下面是一个关于 Azure 资源的表格概览,列出了每个平台服务所使用的资源、它们的用途,以及每个资源的更多信息链接:

Azure 资源 通用用途 链接 Azure 服务面料 分布式系统平台,便于部署和管理可扩展的微服务和容器。 docs.microsoft.com/en-us/azure/service-fabric/service-fabric-overview Azure 密钥保管库 用于加密和解密应用程序中的数据以及其他若干安全相关功能。 docs.microsoft.com/en-us/azure/key-vault/key-vault-whatis 应用网关 用于智能分配应用程序调用的 Web 流量负载均衡器。 docs.microsoft.com/en-us/azure/application-gateway/overview SQL 弹性数据库池 用于 Azure SQL 数据库的资源优化器,适用于客户和应用程序租户。 docs.microsoft.com/en-us/azure/sql-database/sql-database-elastic-pool 应用洞察 一组用于收集日志信息并将其作为遥测数据发送的工具。 docs.microsoft.com/en-us/azure/application-insights/app-insights-overview Azure Machine Learning (ML) 服务 基于 SaaS 的实验室,用于开发和应用机器学习模型及其结果。 docs.microsoft.com/en-us/azure/machine-learning/service/overview-what-is-azure-ml Azure 搜索 为应用程序和微服务实现高级搜索的 API。 docs.microsoft.com/en-us/azure/search/search-what-is-azure-search Azure 存储 提供存储层抽象,以根据安全性和隐私性保存数据。这些存储反映了区域性的法律模型。 docs.microsoft.com/en-us/azure/storage/ Azure Active Directory (AD) 微软基于云的身份和访问管理服务。保证安全、可靠的登录和资源访问。 docs.microsoft.com/en-us/azure/active-directory/fundamentals/active-directory-whatis Azure Function 提供特定例程/功能的 API,运行在隔离环境中。建议作为 Dynamics 365 Business Central 和 .NET 互操作性的替代方案。 docs.microsoft.com/en-us/azure/azure-functions/functions-overview Traffic Manager 基于 DNS 的流量负载均衡器,主要目的是将流量负载优化地分配到全球 Azure 区域的服务,同时保证高可用性和响应性。 docs.microsoft.com/en-us/azure/traffic-manager/traffic-manager-overview Azure 负载均衡器 用于保证微服务的高可用性。负载均衡器支持入站和出站场景,并提供低延迟和高吞吐量。它可扩展至数百万个 TCP 和 UDP 应用的流量。 docs.microsoft.com/en-us/azure/load-balancer/load-balancer-overview Azure SQL 数据库 用于管理进出云存储的数据的关系型数据库。 docs.microsoft.com/en-us/azure/sql-database/sql-database-technical-overview Azure 容器注册表 存储所有类型容器部署的基础镜像。通常用于存储沙盒镜像,供开发目的下载使用。 docs.microsoft.com/en-us/azure/container-registry/ Azure 数据湖存储 Gen1 用于分析产生的大量遥测数据。 docs.microsoft.com/en-us/azure/data-lake-store/data-lake-store-overview Azure 服务总线 一种消息中介解决方案,用于解耦应用程序和服务之间的关系,数据在不同的应用程序和服务之间传输。 docs.microsoft.com/en-us/azure/service-bus-messaging/service-bus-messaging-overview 健康监控 Azure 服务面板引入了一套可扩展的分析工具,用于监控系统和/或服务的健康状况。可以根据特定规则创建警报,并发送给值班的运维工程师。 docs.microsoft.com/en-us/azure/service-fabric/service-fabric-diagnostics-overview Azure 虚拟网络 使许多类型的 Azure 资源(例如 Azure 虚拟机)能够安全地相互通信以及与互联网通信。 docs.microsoft.com/en-us/azure/virtual-network/virtual-networks-overview Azure 数据工厂 一种基于云的数据集成服务,允许创建基于数据的工作流,用于自动化数据移动和数据转换。 docs.microsoft.com/en-us/azure/data-factory/introduction Cosmos DB 用于聚合遥测数据并进行进一步分析。 docs.microsoft.com/en-us/azure/cosmos-db/introduction

全球服务只是一些不存储任何数据、仅执行处理活动的服务。它们只是代理,不持有任何数据,主要用于将请求重定向到适当的控制平面和数据平面。

全球服务主要用于将请求重定向到适当的控制平面;实际上,它们仅在用户登录时路由信息。固定的客户端端点根据凭证负责将请求路由到适当的控制平面和数据平面,不需要其他额外信息。

不同世界地区有多个全球服务实例,但它们都通过相同的端点进行访问。流量管理器在它们前面,将请求重定向到最近的实例。这使得 Dynamics 365 Business Central 服务非常高效且性能优越。从统计数据来看,每小时约有 30,000 次请求通过 Dynamics 365 Business Central 全球服务进行路由。接下来,让我们了解这些服务的工作原理和位置。

区域控制平面

这些是具有各自功能并执行特定任务(例如配置、扩展、监控和身份验证)的微服务集合,用于管理应用程序访问、分发和运行时。它们都是内置的,由 Azure Service Fabric 管理。每个区域都有这些服务的子集,因它们遵循所属国家或地区的隐私和法律准则,因此被称为区域服务。

这样做有两个好处:

  • 在处理数据时,遵守特定区域的隐私和安全法律。

  • 靠近数据存储意味着延迟减少,网络性能提高。

控制平面是管理特定数据平面的服务集合。因此,它们与数据平面位于同一区域,并在该区域内分布。

以下是当前构成控制平面的服务:

  • 数据库监控:用于监控租户和应用程序数据库的健康状况,并将遥测数据和统计信息上传到内部分析工具。

  • 弹性池优化器:从弹性池中提取统计信息,并将其上传到内部工具。

  • 扩展管理服务:这是控制平面的核心服务,负责同步守护进程路由和完成服务调用。大致来说,它是一个信息容器。它包含所有数据平面集群和库存的注册表(包括哪些租户在什么集群中,等等)。它的职责是按需创建、升级和管理租户。通常,这项服务会响应同步守护进程的请求或来自区域控制平面的其他服务。

  • 扩展验证服务:对每个租户的扩展进行编译,针对即将推出的应用服务进行检查。这将确定基础应用程序即将发生的更改是否会破坏为该租户创建的私有 IP。这些错误可能会通过 CSP 合作伙伴门户显示给合作伙伴。

  • 健康监控:跟踪租户的状态,如果检测到不健康的 ping,它会发送内部警报。

  • 管理门户:基于 Dynamics 365 Business Central Web 客户端平台的内部仪表板门户。它管理客户租户,并提供一个 UI 以对这些租户执行操作。

  • 管理服务:服务编排的核心。它包含一个目录,列出租户可以/应该执行的活动类型。这些活动包括创建、复制、升级和删除等。

  • 配置服务:历史上,它由一组用于 Azure 虚拟机配置的 PowerShell 脚本组成。如今,它主要用于执行扩展验证。

  • 同步守护进程:这是 Dynamics 365 Business Central 最古老的服务之一。全球服务通常会与该服务在区域控制平面中进行交互,它决定是否创建新租户或将请求路由到适当的数据平面。它拥有一个操作数据库,用于排队创建新租户的请求,以防无法立即处理。

  • 租户管理员后台服务:执行与管理中心相关的活动。例如,它负责验证 Web 服务请求,如内容的完整性和业务逻辑的合理性。

  • 租户缓冲服务:通常由管理服务处理。它不断检查已经创建了多少租户,并用新的缓冲租户替换原有租户数量,以应对高峰期并保持新租户创建与现有租户分配之间的正确平衡。

  • 租户维护服务:用于租户维护。例如,当客户决定从试用版转到付费订阅时,此服务将启动。维护服务随后会将租户从标准级别迁移到性能更强的高级版。如果试用版过期、AAD 中的许可证被移除,或客户停止付款,维护服务将把租户置于暂停状态。租户有 90 天的赎回期,但这可能因各国的数据保留政策而有所不同。宽限期结束后,租户将被从服务层中移除,并且经过一段时间后将被删除。

  • 租户升级器:在 CSP 合作伙伴指定的时间升级窗口中安排并触发更新任务。目前,租户的升级日期由微软决定,无法更改。

开发团队不断添加新服务或拆分现有服务,以腾出空间为新功能提供支持,或优化 Dynamics 365 Business Central 的维护和可扩展性。在接下来的部分,我们将看到哪些区域数据平面与这些服务配合使用。

区域数据平面

区域数据平面是服务的集合,用于实现安全的客户数据存储。将数据保存在与客户接近的、位于相同国家/地区的 Azure 数据中心,并且位于与客户相同的隐私和合规区域中非常重要。数据安全性至关重要。例如,在西欧地区创建了两个数据平面,这两个数据平面都由四个数据中心提供支持。它们是标准且公开可用的,任何人——包括开发团队——都可以使用它们,释放 Azure 服务、API 及其扩展性的潜力。

在 SaaS 解决方案中,采用隔离的微服务非常重要,这样才能在各个模块中快速部署更新和变更。数据平面同样适用,可以通过所谓的内部安全部署实践应用所需的原子性,进行计划中的更新。

数据平面资源专门用于处理客户数据。这些资源通过大量的遥测参数进行持续测量。所有数据平面的管理,例如创建和升级租户,由其他区域实体(称为控制平面)执行。

这是当前区域数据平面(截至 2019 年 10 月)及其托管的本地化版本列表:

西欧 北欧 美国 加拿大 **亚洲/**中东 非洲 大洋洲 奥地利 丹麦 墨西哥 加拿大 香港(CSP) 南非(CSP) 澳大利亚 比利时 爱沙尼亚(CSP) 美国 日本(CSP) 新西兰 法国 芬兰 马来西亚(CSP) 德国 冰岛 泰国(CSP) 意大利 挪威 韩国(CSP) 荷兰 瑞典 台湾(CSP) 塞尔维亚(CSP) 阿联酋(CSP) 西班牙 印度尼西亚(CSP) 瑞士 新加坡(CSP) 英国 波兰(CSP) 葡萄牙(CSP)

一个数据平面集群包含所有冗余的虚拟机和用于应用程序和客户租户的 Azure SQL 数据库。目前,通过为每个数据平面负载均衡五个 Azure 虚拟机,确保了高可用性。

由于这些统计数据表明租户大约每三分钟生成一个,如何在多个请求同时到达同一数据平面时应对并扩展如此高的负载呢?这一过程通过相当智能的方式处理。当一个区域控制平面指示创建新租户时,管理服务会在数据平面集群中预留一个缓冲租户。什么是缓冲租户?基本上,它是一个已经创建的租户,数据库中有一个带有示范数据的公司,充当预包装模板。缓冲租户不与任何应用服务绑定(未挂载)。

当预留一个缓冲租户时,它不能被任何其他管理服务调用占用,并且只需通过更改一些配置参数并为特定客户添加生产公司名称,即可将其转变为生产租户。完成后,该租户将与生产服务挂载,当其运行时,连接就绪。

简而言之:预留、配置、挂载、运行,准备就绪。不需要冗长的数据库创建或恢复过程。

目前,生产和沙盒环境中的数据平面集群环境是不同的。这是由于不同环境的特性及其需求不同。它们主要在性能上有所不同,因为不同的 Azure SQL 数据库层级。试用版和沙盒租户目前属于 Azure S 级别。切换到生产环境时,这些租户将被移动到更高性能,并且由 Azure SQL 团队推荐的 P 级别。

单个数据平面集群是微软云技术的聚合体,逻辑上分为计算层和数据层。让我们来探索数据平面的解剖:

服务名称 通用目的 公共 IP 地址 这些根据用户调用(浏览器/ Web 服务)的不同或由控制平面在内部实例化而不同。 应用程序网关 这是一个智能、智能且复杂的第 7 层负载均衡器,能够分析 cookie 和检查有效负载。它用于用户调用,并且仅支持 HTTP 调用。 Azure 负载均衡器 这是用于区域控制平面调用的内部使用。 VM 规模集 默认由五个 Azure 虚拟机组成。可以在 VM 规模集内部署更多 Azure 虚拟机,从而实现无限扩展并能够处理高服务负载或隔离。整个 Azure 虚拟机集合都定义在相同的可用性集合内。这意味着如果发生硬件故障,不会同时影响所有虚拟机,从而保证高服务可用性。VM 规模集内的每个 VM 都包含一个 Dynamics 365 Business Central Web 服务器和 Dynamics 365 Business Central。这有助于优化 Web 服务器和 Dynamics 365 Business Central 之间的流量。每个 Azure 虚拟机还包含一个监控服务,用于收集遥测数据和许可服务,以避免存储用于访问 AAD 租户的证书私钥。 虚拟网络 这用于允许 Azure 虚拟机在 VM 规模集内相互通信。 存储帐户 这包含来自 VM 和服务健康数据的遥测数据。 Azure 服务 Fabric 控制器 这用于管理和编排每个集群中的服务部署。例如,在需要时,可以指示它在规模集中提供新的 VM。 应用程序数据库 这包含标准应用程序代码,并绑定到每个 VM 中的 Dynamics 365 Business Central 服务。即使这看起来像是数据层的一部分,但应用程序数据库实际上并不存储任何客户数据。这就是为什么它与其他计算部分项目一起列出的原因。 网络安全组 这主要用于为每个集群提供额外的安全层。通常,开发团队不允许通过终端服务进行任何远程连接,即使是来自他们自己。Dynamics 365 Business Central 的遥测服务提供有关虚拟机或服务状态的信息,并通过特定的端点提供可操作的洞察。换句话说,数据处理的安全性是完全有保障的。

了解了这个详尽的列表后,我们继续查看数据层级别。

数据层

最简单的数据层就是所谓的每个单独的数据库。这非常容易解释和理解:例如,在 Sx 层级中创建一个 Azure SQL 数据库,如果客户需要更多的性能,你只需将其扩展到 Sx+n,根据需要的资源(你希望处理完成的速度)。

单个数据库的缺点在于,当你在 Azure SQL 中创建了数据库后,所有的资源都会被分配出去,这些资源既不会共享也不会释放,而客户——或者你——都需要为这些资源支付费用,无论是否使用它们。

当你需要处理成千上万(甚至数十万个)数据库时,就像在每个多租户的 A 类产品中一样,资源分配设计应该足够智能,能够在需要时分配或释放资源。否则,这将变成一个对所有人来说的成本杀手:客户、合作伙伴,甚至微软自己。

Dynamics 365 Business Central 数据库资源分配是智能的。它依赖于 Azure SQL 弹性池技术。基本上,通过 Azure SQL 弹性池,可以定义一个在池内共享的资源总量,并为每个数据库租户设置一个范围(最小值和最大值)。云资源治理器会在池内智能分配资源。这非常高效、性能优越且成本效益高。

值得一提的是,存在 标准Sx)和 高级Px)弹性池数据层。当需要时,Sx 的租户会被移动到性能更高的 Px 池中。

所有生产数据库当前都运行在 Px 弹性池数据层中。

数据层通过基于 WCF 的 Navision 服务层NST)进行访问,NST 安装在另一个名为 VM 扩展集的微服务中。以下是单个虚拟机扩展集的当前结构:

Web 服务器 Dynamics 365 Business Central Web 服务器组件 NST Dynamics 365 Business Central 服务器服务。出于安全原因,它在 Hyper-V 容器中以主机模式隔离(如小型虚拟机)。这防止了恶意代码访问用户的秘密。 监控代理服务 用于收集来自当前 Azure 虚拟机状态的遥测数据。此服务还会收集来自平台和应用程序日志的遥测数据,涵盖 Web 服务器和服务器服务组件。 许可服务 这是 2018 年秋季更新中为安全原因引入的一项服务。该服务负责检查 AAD 中是否存在有效的许可证,其 API 由 NST 组件调用。 租户目录 这是一个包含租户名称及其连接字符串的集合。通常由另一个服务(如许可服务)访问,以避免通过应用数据库租户列表从 NST 进行破坏性攻击或直接调用。 混合代理 该功能启用混合复制,使我们可以将本地数据迁移到云端。你可以在docs.microsoft.com/en-us/dynamics365/business-central/dev-itpro/administration/about-intelligent-edgedocs.microsoft.com/en-us/dynamics365/business-central/about-intelligent-cloud了解更多。 扩展服务 该服务允许为每个租户异步安装扩展。 差异服务 该服务使对 Dynamics 365 Business Central OData 服务端点的差异查询成为可能。 浏览器客户端 该组件托管了 Web 服务器的静态部分(例如 .js 文件等)。 网关服务 这是一个以性能为驱动的服务工件,用于智能请求路由。该服务如果同一租户已经创建了其他会话,会将请求重定向到所谓的“预热”服务。它通过应用程序和数据对象预热内存缓存。 任务触发服务 该服务用于优化计划任务的执行,并提高任务执行时(加速启动)和执行上下文中的性能(即,如果存在,将其路由到一个预热的 NST)。

现在我们已经解锁了服务并了解了 Dynamics 365 Business Central 的底层架构,让我们快速回顾一下它未来的发展方向。 |

理解未来的视角

Azure 和 Office 365 现在被认为是成熟且稳定的,并且为客户带来了可观的 投资回报率 (ROI)。 |

它们是微软收入的最佳来源之一,也是微软最重视的投资领域。所有微软服务都要求与微软战略对齐,促进这两项旗舰服务的使用。

Dynamics 365 Business Central 完美契合了微软的战略:它为潜在的 SMB ERP 客户提供了一个平台,旨在加速 Microsoft 一流云服务的使用。 |

换句话说,潜在的 Dynamics NAV 和 Dynamics GP 客户强烈建议订阅 Dynamics 365 Business Central 的 Essential 或 Premium 版本,而不是选择传统的本地部署方案。 |

在最近的微软及非微软活动中宣布了一项推动在线采用的巨大产品转型。这些行动主要针对现有的 Dynamics NAV 和 Dynamics 365 Business Central 本地客户。以下是最近在 Directions EMEA 上展示的产品当前路线图(www.directionsemea.com/):

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/ms-ms-dyna365/img/9bced2fe-3228-4297-bc86-e189c6475aaf.png

在 2019 年秋季发布时,微软实现了一个具有挑战性的目标,即缩小本地部署和在线部署之间的差距。现在这两种产品的部署能力几乎相同:

  • 仅使用现代客户端:不再为本地发布部署 Windows 客户端。

  • 仅限扩展开发:不再通过 CSIDE 或混合模式对本地发布进行遗留代码的更改。标准代码更改只能在本地进行,即使尽可能避免这些更改。更多信息请参见 www.waldo.be/2019/08/06/al-baseapp-customization-because-you-can-doesnt-mean-you-should/

根据开发团队的公告,当前的计划是将现有的遗留 C/AL 代码迁移到 AL,并提供作为微软本地化扩展的标准代码,或者更可行的是,作为一系列依赖应用程序提供。

通过这种方式,本地和在线客户端的访问在用户和开发体验方面将大致相同。然后,本地与在线之间的差异将非常小,且从本地迁移到在线只需一步即可轻松完成。

由于这项工作是一个持续的进程,Dynamics 365 Business Central 的开发团队始终保持开放,并以主动和反应性服务倾听所有客户和合作伙伴的请求。这是为了涵盖所有不同的视角和观点。在接下来的部分,我们将具体了解微软如何倾听并采取行动响应客户和合作伙伴的请求。

主动场景(微软倾听)

让我们来看一下微软 Dynamics 功能和版本的一些主动场景:

  • 新功能建议以及现有功能和能力的增强建议: 这会直接在 Dynamics 365 Business Central 的工程积压中创建一个内部记录。你还可以对现有的建议进行投票,这会提高该功能的优先级和排名。此项工作直接由开发团队处理(aka.ms/bcideas)。

  • 在应用程序或平台的预览版或测试版中发现的错误或问题: 仅限 独立软件供应商ISV)/增值经销商VAR)。请注意,不接受任何咨询或建议请求(docs.microsoft.com/en-us/collaborate/)。

  • **在 Visual Studio Code 中的 AL 预览版或测试版中发现的 Bugs 或错误:**需要注意的是,不接受任何咨询或顾问请求(github.com/microsoft/al)。

新的事件请求

功能暴露请求将添加到预览版发布中,而不会添加到当前的在线版本。如果需要将更改回移植到当前的在线堆栈,应提出一个响应性请求(github.com/microsoft/ALAppExtensions/)。

响应性场景(微软行动)

以下是微软针对响应性场景的规则:

  • **在 GA 版本和主流支持版本中发现的应用程序或平台中的 Bugs 或错误:**仅适用于与微软签订 高级合作伙伴支持 (ASfP) 合同的 ISVs/VARs。

  • **回移植在 GA(正式发布)版本和主流支持版本中暴露的新事件或功能:**在线客户必须联系其销售商或 CSP 合作伙伴以获得支持和/或要求他们提交响应性支持请求。

更多信息可以在此找到:community.dynamics.com/business/b/financials/archive/2018/12/04/find-the-right-resources-and-provide-feedback

总的来说,考虑到仍在使用本地部署的 Dynamics NAV 和 Dynamics GP 的现有客户,我们可以提供给客户和合作伙伴组织的最佳建议如下:

  • 使用和请求事件。

  • 尽可能将所有现有的私有 IP 移到事件驱动开发的标准代码之外。如果这需要在标准应用程序中新增事件,请通过适当渠道提出请求。

  • 将遗留代码迁移到扩展中。

  • 所有可以隔离成事件驱动开发的内容,都可以打包成扩展。尽可能将私有 IP 移到扩展中。这项任务有一个广泛接受的技术术语,叫做 SaaS 化

  • 重构所有代码,以使其在 Web 客户端中工作,并将所有技能集中于基于 Web 的开发。

  • 使 Web 客户端成为你的主要客户端,并将思想转向 Web 导向开发。

  • 培训所有销售人员、安装人员、开发人员、功能应用专家以及其他所有使用或演示 Web 客户端的人。让他们在 Dynamics 365 Business Central Web 客户端中“活在其中”。

  • 合作并利用社交媒体。

  • 保持 LinkedIn、Twitter 和 Yammer 上的最新动态。注意你自己的业务流程瓶颈,并通过积极参与官方和非官方论坛以及专门的产品活动,与 Dynamics 365 Business Central 社区和开发团队分享。

  • 最后但同样重要的是,主要针对合作伙伴和自由职业者,习惯并专注于现代技术。

我们建议开发人员掌握以下相关技能:

  • Visual Studio Code 和 AL

  • JavaScript 和基于 Web 的开发

  • 人工智能与机器学习技术

  • 针对开发者的 Azure 服务(如 Azure Functions 和 Cognitive Service)

  • Git 和 Azure DevOps

开发者和架构师应熟悉以下内容:

  • Docker 容器

  • Azure 计算服务(如 Azure 虚拟机和 Azure 存储)

  • Office 365 服务和 Dynamics 365

  • 通用数据模型CDM)/通用数据服务CDS

强烈建议合作伙伴订阅 Dynamics 365 Business Central Ready to Go 项目,并从其不断更新的学习目录中受益。您可以在docs.microsoft.com/en-us/dynamics365/business-central/dev-itpro/developer/readiness/readiness-ready-to-go?tabs=learning了解更多信息。

总结

本章节介绍了目前和未来在 Dynamics 365 Business Central 中可用的功能。

首先,我们从合作伙伴和客户的角度出发,重点介绍了 Dynamics 365 Business Central。这将有助于您理解该产品在本地化、功能以及您想要针对的小型企业市场领域方面能够提供的价值。

接下来,我们介绍了合作伙伴中心和 Dynamics 365 Business Central 管理中心门户以及如何使用它们。然后,我们讲解了 Microsoft Dynamics 365 Business Central 的主要技术特性,并对架构元素进行了概述。本章最后简要介绍了未来可能发生的变化、如何为此贡献力量以及如何成为 Microsoft SaaS 解决方案演进的一部分。

在下一章中,我们将深入探讨 Visual Studio Code、AL 语言扩展以及现代开发环境。

第二章:精通现代开发环境

在上一章中,我们介绍了 Dynamics 365 Business Central,并揭示其骨架是 Microsoft 云微服务。

在本章中,我们将深入了解开发环境。我们将讨论与 Visual Studio Code(官方开发平台)以及 AL 语言(开发语言扩展)相关的主要快捷键、技巧和窍门。Visual Studio Code 与 AL 语言的结合定义了所谓的现代开发环境。

AL 是 Microsoft 提供的官方扩展,免费通过在线市场提供。该扩展于 2017 年正式发布,用于扩展当时被称为 Dynamics 365 for Financials 的功能,现在它已经成为一个完整的开发语言,扩展了 Dynamics 365 Business Central。它提供了许多功能,大大提升了开发者的生产力和编码质量。

本章的主要目标是帮助 Dynamics 365 Business Central 开发人员了解开发平台所提供的功能,释放他们的全部潜力,并提高他们在日常编码活动中的熟练度。

在本章中,你将学习以下内容:

  • Visual Studio Code 用户界面由哪些部分组成,每个部分的作用是什么

  • 如何熟练使用 Visual Studio Code 中最强大的编辑功能

  • AL 语言扩展是什么,它包含了哪些内容

精通 Visual Studio Code

Visual Studio Code 是全球使用最广泛的开发环境之一。它的设计目的是让云端和基于 Web 的应用程序设计变得简单快速,支持多种可扩展的编程语言。该应用程序专注于最大化代码编辑效率,同时通过提供有用的快捷键,帮助开发者在特定开发场景下快速访问所需的功能,充分释放开发者的潜力。

当你启动 Visual Studio Code 时,首次安装后,它会显示典型的欢迎页面:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/ms-ms-dyna365/img/a7f9c7c7-a01f-41c0-b3ca-69be7d020562.png

欢迎页面包含以下内容:

  • 开始:创建和打开文件及文件夹的快捷键

  • 最近:最近打开的文件和文件夹列表

  • 帮助:文档单页、产品文档、视频和有用资源的列表

  • 自定义:如何通过扩展、键盘快捷键、背景色主题等来自定义 Visual Studio Code

  • 学习:与最常用命令相关的学习资源快捷键,以及如何掌握用户界面

每次你以新窗口运行 Visual Studio Code 时,都会加载欢迎页面(Ctrl + Shift + N)。你可以通过取消勾选启动时显示欢迎页面,或点击“文件 | 偏好设置 | 设置”并搜索“欢迎页面”来更改此行为。

Visual Studio Code 环境分为五个主要区域:

  • 代码编辑器

  • 状态栏

  • 查看栏

  • 侧边栏

  • 面板区域

接下来我们将分别讨论这些内容。

代码编辑器

代码编辑器是你编写代码并花费大部分时间的地方。当创建新文件或打开现有文件或文件夹时,它会被激活。

你可以只编辑一个单独的文件,或者你也可以加载并同时处理多个文件,排成并排的方式:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/ms-ms-dyna365/img/4f708006-72d4-4eb9-8294-030702726dc6.png

有几种方法可以查看多个文件;这里提到的三种是:

  • 在 EXPLORER 栏中选择一个文件名,然后右键点击并选择“在侧边打开” (Ctrl + Enter)。

  • 在 EXPLORER 栏中 Ctrl + 点击文件名。

  • Ctrl + ** 将编辑器分割为两部分。

它可以容纳多个文件,将空间平均分配给它们。你可以通过简单地按下 Ctrl + 1Ctrl + 2Ctrl + 3,……,Ctrl + N 在不同的文件编辑器之间切换。

编辑器窗口可以根据你的需求进行调整大小、重新排序和缩放。要缩放,按 Ctrl + +Ctrl + -,或者通过 View | Zoom in / Zoom out。

缩放适用于所有 Visual Studio Code 区域,而不仅仅是代码编辑器。

Visual Studio Code 还提供了一种便捷的方式来通过快捷方式在文件之间导航。最快的方法是按 Ctrl + Tab。这将打开自 Visual Studio Code 启动以来打开过的文件列表。

状态栏

状态栏通常包含关于当前选中文件或文件夹的信息。它还提供一些可操作的快捷方式:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/ms-ms-dyna365/img/27851c2c-a1e8-4fac-acbd-16d4361fabe5.png

从左到右,状态栏包含以下信息:

  1. 如果启用了 Git,它将报告版本控制信息,例如当前分支。

  2. 当前代码中检测到的错误和/或警告数量。

  3. 光标位置(行号和列号)。

  4. 缩进大小和类型(空格或制表符)。

  5. 当前选中文件的编码。

  6. 行终止符:回车符CR)和/或 换行符LF)。

  7. 用于处理选中文件中代码的语言。如果点击该语言,菜单会出现,你应该能够更改处理的编程语言。

  8. 反馈按钮,你可以通过它在 Twitter 上分享关于 Visual Studio Code 的反馈。

  9. 通知图标。它显示新的通知数量,通常与产品更新有关。

状态栏有一种常规的颜色显示,它会根据当前正在处理的内容而变化。打开文件时是紫色,打开文件夹时是蓝色,调试时是橙色,等等。

视图栏

这是工作区的左侧,包含通往侧边栏的快捷方式。如果点击一个快捷方式,属于所选工具的侧边栏将变得可见。再次点击,或按 Ctrl + B,它将消失。

侧边栏

侧边栏是你与代码编辑器互动最多的地方。它是上下文敏感的,你会在视图栏中看到五个标准活动,每个活动都由相应的图标启用。

EXPLORER (Ctrl + Shift + E)

EXPLORER 提供了你当前正在使用的文件夹和文件的结构化和组织化视图。OPEN EDITORS 子视图包含代码编辑器中活动文件的列表。在此部分下方,可能会有另一个子视图,显示已打开文件夹的名称:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/ms-ms-dyna365/img/fa48f11f-e75f-46e3-ab38-92cc85b3ed93.png

如果你将鼠标悬停在 OPEN EDITORS 子视图上,将显示三个操作按钮:切换垂直/水平编辑器布局(Shift + Alt + O)、全部保存(Ctrl + K + S)和关闭所有文件(Ctrl + KCtrl + W)。它们都是显而易见的:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/ms-ms-dyna365/img/c29f2344-95cf-4321-922a-994a3d1a1382.png

将鼠标悬停在文件夹名称上(在此示例中为PW_V2),四个操作按钮将变得可见:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/ms-ms-dyna365/img/c92ee73d-c3bd-45d5-93e2-c3482cba03e4.png

从左到右,分别是新建文件、新建文件夹、刷新和全部折叠。它们是显而易见的。

右键单击文件夹或文件名,将打开一个上下文菜单,显示常用命令,如在资源管理器中显示(Shift + Alt + R),它将打开包含选定文件的文件夹。你还可以通过复制路径(Shift + Alt + C)来复制文件路径。

在 EXPLORER 栏的下方,还有一个叫做 OUTLINE 的部分。它为特定文件提供了非常有用的树形视图,显示了文件中的成员和类型。请参见以下截图:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/ms-ms-dyna365/img/cc0c3d16-ed4a-416d-85ef-30d6fa793a63.png

当你正在开发复杂对象并希望通过点击一下跳转到特定区域时,这确实是一个强大的选项。

搜索 (Ctrl + Shift + F)

这是一个强大的工具,用于在文件中搜索和替换文本。你可以选择一个或多个关键字进行简单搜索,还可以使用通配符如*和?。或者,你可以选择基于正则表达式(regex)创建复杂搜索。还有高级选项可以包括或排除文件或文件类型。

当开发者在扩展文件夹中搜索where used字段或变量时,这一功能非常有帮助。请参见以下截图:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/ms-ms-dyna365/img/b5654c6c-42b5-45b6-a987-ac5e247a165b.png

搜索结果以树形视图列出,显示包含搜索关键字的所有文件,并显示与该行相关的小段代码。树形视图中的关键字匹配处以及代码编辑器中的匹配处都会被高亮显示。通过点击“全部折叠”按钮,可以将所有结果折叠。

你可以通过点击“清除搜索结果”按钮来重置搜索结果。

源代码控制 (Ctrl + Shift + G)

Visual Studio Code 提供了与最广泛使用的源代码控制管理系统之一:Git 的原生集成。Git 的基础知识和集成将在第十一章中讨论,源代码控制管理与业务中心的 DevOps

调试 (Ctrl + Shift + D)

Visual Studio Code 不仅仅是一个用于编辑文件的代码编辑器。它还提供了一个开箱即用的集成调试框架,可以扩展用于调试不同的平台和语言。

Visual Studio Code 并不提供针对 Dynamics 365 Business Central 的调试功能。这项功能嵌入在 Visual Studio Code 的 AL 语言扩展中,扩展了现有的 .NET 核心调试器。在第九章中,调试,我们将详细讨论这一议题。

EXTENSIONS(Ctrl + Shift + X)

扩展用于浏览 Visual Studio Code 的在线市场,市场中包括了不断增长的额外语言、调试器、工具、助手等各种扩展。AL 是 Microsoft 开发的一个 Visual Studio Code 扩展。在 Visual Studio Code 市场中,你还可以下载几个有用的扩展,它们扩展了(对扩展的扩展)AL 语言扩展,帮助 Dynamics 365 Business Central 开发者提高工作效率,提升生产力,并且编写专业的代码。

请参考以下截图,展示了为 Dynamics 365 Business Central 安装的典型 Visual Studio Code 扩展:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/ms-ms-dyna365/img/d275b3b5-962b-4c68-96a5-cf7c8c157c41.png

在 EXTENSIONS 栏中,可以搜索在线市场或手动安装扩展。你还可以查看已安装、过时、推荐和禁用的扩展,并根据不同标准对其进行排序。

一些扩展包旨在下载并安装一组扩展。在 Dynamics 365 Business Central 中,你可以考虑从 marketplace.visualstudio.com/items?itemName=waldo.al-extension-pack 下载并安装 AL 扩展包,或从 marketplace.visualstudio.com/items?itemName=StefanoDemiliani.sd-extpack-d365bc 下载并安装 Dynamics 365 Business Central 的 SD 扩展包。

也可以通过右键点击单个扩展来执行相关操作。扩展可以被启用、禁用、按工作区禁用(工作区可以是项目或文件夹)等。最新、最酷的功能之一是能够安装该扩展的另一个版本。

这对于 Dynamics 365 Business Central 开发者非常有用,特别是在高版本 AL 语言扩展中存在回归行为或错误时。请参考以下截图,展示当前在线 AL 语言扩展版本:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/ms-ms-dyna365/img/61b66e0d-7a6a-4415-ae84-9a75f4efa0e6.png

这在开发针对特定平台版本的功能时也非常有用。

管理

管理按钮以齿轮图标显示在视图栏的最底部:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/ms-ms-dyna365/img/78f519d1-07cc-4959-9bc8-1d0cccf3c727.png

如果你点击它,会弹出一个菜单,列出可用的命令。这些命令用于自定义 Visual Studio Code 或查找更新。

命令面板

命令面板是 Visual Studio Code 中最重要的工具之一。它的作用是快速访问标准和扩展命令。运行命令面板有不同的方式:

  • 管理 | 命令面板

  • 查看 | 命令面板

  • 键盘快捷键:Ctrl + Shift + P(大多数开发者常用)

命令面板不仅可以显示菜单命令,还可以执行其他操作,例如安装扩展。你可以浏览命令面板,查看可用命令的庞大列表。命令是按索引排列的,并且可以搜索。只需输入几个字母,就能得到筛选后的列表。值得一提的是,大多数这些命令都有对应的键盘快捷键。

了解命令面板时,有一件非常重要的事需要知道,那就是 > 符号的使用。当你按下 Ctrl + Shift + P 时,命令面板会弹出,并带有 > 符号,显示可用命令的列表。请看以下截图:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/ms-ms-dyna365/img/a066bda5-23f0-4bb2-8513-3393964c45d2.png

如果你移除 > 符号,Visual Studio Code 会使用命令面板显示最近打开的文件列表。以下截图展示了这一点:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/ms-ms-dyna365/img/9b7b15e3-3221-4eec-a1eb-fa5af09c2265.png

这一功能的强大之处在于,在不使用鼠标的情况下,你可以打开命令面板,运行命令,移除 **>** 字符,并选择要编辑的文件。这对提升开发效率非常有帮助。

面板区域

Visual Studio Code 不仅显示与代码相关的详细分析和信息,还能访问并展示来自其他来源的信息,例如 Git、已安装的扩展和调试器。这些输出会记录到面板区域,默认情况下显示在底部,但可以通过右键单击面板标题栏并启用“Move Panel Right”按钮轻松将其移动到工作区的一侧。可以通过点击“Move Panel to Bottom”按钮恢复原始布局,或者甚至通过按 Ctrl + J 隐藏面板。

面板区域默认不可见。当请求所需信息时,通常会启用并显示此区域,例如启用调试器时。

在面板区域,有四个不同的窗口:PROBLEMS、OUTPUT、DEBUG CONSOLE 和 TERMINAL。我们将在接下来的章节中逐一讲解它们。

PROBLEMS

对于具有高级编辑功能的语言,例如 AL,Visual Studio Code 能够在输入时识别代码问题。问题所在的行会有特定的颜色标记。通知类型有三种:错误、警告和信息。所有这些都可以在 PROBLEMS 窗口中显示。以下截图展示了 PROBLEMS 窗口显示三条错误的示例:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/ms-ms-dyna365/img/ad029571-2909-437c-b64e-357397394937.png

通常,阻塞错误会以红色显示,而警告则以绿色标记。

OUTPUT

OUTPUT 面板是 Visual Studio Code 通常在命令执行期间或执行后显示消息的地方。

由于内置工具操作和多个扩展命令可以并行运行,因此可以利用 OUTPUT 面板中的下拉框更改视图,查看每个标准或基于扩展的命令的输出。

以下截图显示了面板区域中的 OUTPUT 窗口:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/ms-ms-dyna365/img/c61fee8b-c3b0-4b1c-9d02-81aad6e2ada3.png

通常,在处理 Dynamics 365 Business Central 扩展时,会选择 AL 语言。

DEBUG CONSOLE

这是一个由本地和基于扩展的调试器(例如 AL 语言调试器)使用的特殊窗口,用于显示关于代码执行的信息。此窗口及其输出将在第九章中详细分析,调试

TERMINAL

Visual Studio Code 允许我们像在命令提示符中一样直接在开发环境内执行命令。默认情况下,终端会话基于 PowerShell。

现在我们已经了解了与 Visual Studio Code 相关的所有元素,可以进入下一部分,分析它所提供的强大编辑功能。

Visual Studio Code – 编辑功能

Visual Studio Code 提供了你所期待的顶级代码编辑器的许多功能。如果你熟悉 Visual Studio,你可能已经注意到一些功能是从这个 IDE 继承过来的,或者是以类似的方式设计的。

由开发人员为开发人员开发,Visual Studio Code 为几乎所有编辑命令提供键盘快捷键,让你可以更快地编辑代码,完全摆脱鼠标的依赖。

让我们在接下来的章节中研究这些功能。

注释行

Visual Studio Code 提供了开箱即用的文本选择和专业编辑命令,这些命令位于编辑菜单中。编辑菜单还包括切换行注释(Ctrl + U),该命令为选中的行添加行注释。这意味着,如果你选择了 10 行代码,Visual Studio Code 会添加 10 行注释。这个命令的妙处在于它也能反向操作。如果你选择了 10 行注释并按下切换行注释,注释就会神奇地被移除。

对于使用 CSIDE 的开发人员来说,CSIDE 是 Dynamics 365 Business Central 传统本地语言,此命令等同于注释选择(Shift + Ctrl + K)和取消注释选择(Shift + Ctrl + O)。

定界符匹配

Visual Studio Code 能够检测配对的定界符,如括号和圆括号。如果你想划定代码块,这个功能非常有用,当鼠标靠近某个定界符对时,它会自动触发:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/ms-ms-dyna365/img/89e5b9dc-75f4-43e5-9c85-af684ad075a4.png

上述代码是定界符匹配的示例。

文本选择

选择菜单也有与文本选择相关的命令,但大多数用于移动或复制选中行的代码。

如果你将光标放置在 AL 函数、变量或常量附近,可以使用“添加下一个出现位置”(Ctrl + D)、“添加上一个出现位置”或“选择所有出现位置”(Shift + Ctrl + D)来选择所选项的所有出现位置,并且这些出现位置会以不同的颜色高亮显示。

在代码编辑器中,你还可以按Ctrl + D选择光标右侧的单词或标识符。然后,你可以轻松地扩展(Shift + Alt + →)或收缩(Shift + Alt + ←)分隔符内的文本块。

代码块折叠

如果你将鼠标悬停在代码编辑器中的行号上,-符号会出现在代码块的起始部分旁边。点击它进行折叠,此时会出现+符号。点击这个符号,代码块会展开:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/ms-ms-dyna365/img/e5002d69-7f9f-4594-872c-e0e05641d6c0.png

上图展示了代码块折叠的情况,使用了+符号。

多光标(或多重光标)

每个光标都是独立操作的。Alt + 点击将在目标位置生成一个次要光标。

最常见的开发场景是,当你需要在同一源文件中的不同位置添加或替换相同的文本时,你可以使用多光标。下图展示了在编辑DataClassification属性时,三个光标的使用情况:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/ms-ms-dyna365/img/9cc8d80f-aa7b-42ec-be6f-c5919670e0fb.png

对于 AL 语言开发者来说,这是一个很棒的功能,特别是当他们需要在同一个地方多次写下相同的句子时(例如,在表格对象中的CaptionDataClassification,以及每个表格字段中)。

迷你地图

有时,当处理非常长的文件(例如报告源文件 RDL 或代码单元)时,很难知道指针应该定位到哪里——或者它当前位于源文件的哪个位置。Visual Studio Code 提供了一个完整的迷你地图功能:源代码文件的一个小预览。以下是一个 RDL 示例:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/ms-ms-dyna365/img/feba5994-d844-48b3-8842-e3a1040feaf7.png

迷你地图功能可以通过视图 | 切换迷你地图进行启用或禁用,或者通过运行命令面板(Ctrl + Shift + P)并选择“视图: 切换迷你地图”来操作。

面包屑

“显示面包屑”命令可以在视图菜单中找到。在 AL 文件中,代码编辑器的左上角有一个图标。可以展开它,以便重新检查属性、函数、字段、键等的定义:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/ms-ms-dyna365/img/49acd2a0-3d17-436b-b698-7b3cf2032347.png

如果你点击展开列表中的某个元素,光标将跳转到该元素的主定义位置,使得代码导航非常快捷。

IntelliSense(智能感知)

在视觉编辑器中,IntelliSense 是一个单词自动补全工具,它会在你输入时作为弹出列表出现。Visual Studio Code 的 IntelliSense 可以提供智能建议,显示与特定元素相关的定义和用途——就像在线帮助一样。下图展示了 IntelliSense 的使用情况:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/ms-ms-dyna365/img/efe59c67-97ef-442c-bfaa-c34e8d82c6fa.png

IntelliSense 是上下文敏感的,如果你需要直接启用它而不输入任何内容,只需按 Ctrl + 空格键。根据光标所在的上下文,IntelliSense 会显示该上下文中可以使用的所有项。例如,在 Table Field 声明内部,它会列出所有特定字段属性,如 CaptionCaptionML,而在空代码单元定义中,它会显示代码单元对象暴露的所有属性。

单词自动补全

通过 IntelliSense 功能,Visual Studio Code 中的代码编辑器实现了对所有原生(如 JSON)和基于扩展支持的语言(如 AL)的单词补全。只需按 EnterTab 即可插入建议的单词:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/ms-ms-dyna365/img/4cf2e797-aaba-49c1-90b1-8fc4ee162fdd.png

上面的截图展示了单词自动补全引擎推荐的一个 AL 变量。

定义跳转

这是一个超级酷、必须了解的功能。你可以用鼠标悬停在变量、常量、函数或任何你想要的代码元素上,然后按 Ctrl,该单词或标识符(也称为符号)会神奇地变成一个超链接。

如果你在按下 Ctrl 的同时点击该单词,你将自动跳转到定义该单词的代码位置。Ctrl + 鼠标悬停在代码元素上也会启用跳转到定义功能。

启用此功能的其他可能方式如下:

  • 选择一个代码元素并按 F12

  • 右键点击一个代码元素,然后从上下文菜单中选择“跳转到定义”。

查找所有引用

查找所有引用可以非常方便地解析一个对象、函数或任何代码元素在源代码中被使用的次数和位置。你只需右键点击任何变量、函数或元素名称,然后选择“查找所有引用”,或者使用快捷键 Shift + Alt + F12

当它被启用时,代码编辑器会在活动栏中创建一个结果列表,显示该项被引用的次数,以及在哪些对象文件和位置(s)中引用过。侧边栏中会创建一个名为“引用”的快捷图标。下图展示了如何查找 AL 文件中特定变量的所有引用:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/ms-ms-dyna365/img/e8a84e83-55b5-4157-9ae4-69c40c107ff6.png

如果你在左侧的引用列表中展开一个出现项并点击记录,代码编辑器会打开引用该项的文件,并将光标定位到编辑模式,选择该文件中搜索到的元素。

参考列表可以清除并刷新,你可以折叠其中的所有元素。如果清除列表,你可以随时重新运行先前的搜索,因为系统会为你保留历史记录。

Peek Definition

想象一下你有大量的代码文件,你需要编辑当前正在使用的变量或字段的定义。在许多其他编辑器或开发环境中,你可能需要将所有文件保存为文本格式,然后搜索所有这些代码文件,确保替换该变量名。这个任务不仅可能很烦人,而且会让你分心,远离你原来正在编写的代码。

Visual Studio Code 通过提供 Peek 功能来解决这个问题,可以通过不同的方式启用:

  • 右键单击变量、字段或函数名,然后选择 Peek Definition。

  • 使用 Alt + F12 键盘快捷键。

应该会弹出一个交互式弹出窗口,显示定义所选元素的源代码。以下截图显示了报表中表源 Peek Definition 的窗口:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/ms-ms-dyna365/img/067889db-7662-4f38-ade8-fe051f70dbc0.png

然后,你可以看到已经编写的内容,也可以直接编辑它。

重命名符号

对于开发人员,重命名变量、常量、字段或函数名是非常常见的。这些编码元素在技术上称为符号。Visual Studio Code 提供了一个非常强大的功能来重命名符号。

如果你在想要重命名的编码元素上按 F2,或者右键然后选择重命名符号,一个小的交互式弹出窗口会出现在编辑模式中。在那里,你可以写入新的元素名称,而无需使用分散注意力的对话框窗口,让你可以集中精力编写代码。所有对该代码元素的引用都将相应地被重命名。以下截图显示了重命名 XMLport 符号引用的过程:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/ms-ms-dyna365/img/79a77faa-f447-4432-b5bd-aa42e2566001.png

到目前为止,所展示的所有功能都是 Visual Studio Code 提供的最有用的功能,支持 AL 开发人员进行高效的代码编辑。

在这个阶段,重要的是仔细看一下 AL 语言扩展,并了解如何配置它。

理解 AL 语言扩展

AL 现在是一个跨平台语言,通过 Visual Studio Code 的扩展部署。这个扩展不仅支持在 Windows 操作系统上部署,还支持 macOS 版本的 Visual Studio Code。

免费的 AL 语言扩展 (marketplace.visualstudio.com/items?itemName=ms-dynamics-smb.al) 可在 Visual Studio Code 市场上下载。这为 Dynamics 365 Business Central 扩展开发提供了优化的体验,并包括了构建应用程序(从现在起称为扩展的同义词)所需的所有支持和工具,包括调试器。

获取扩展并安装的最简单方法是打开任何 Dynamics 365 Business Central 代码文件(.al),并按照 Visual Studio Code 在检测到该文件类型有可用扩展时显示的说明操作:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/ms-ms-dyna365/img/1e2e7c53-68da-48b4-a4fa-bbc04c788db0.png

同样,你可能想要安装其他扩展,以便为 AL 语言扩展添加其他语言(如 PowerShell)、工具(如 Docker)或增强的编辑功能。关于与 AL 语言结合使用的最有用的市场扩展列表将在第十八章中提供,AL 开发者的有用且高效工具

接下来,让我们了解 AL 语言中的这些扩展。

AL 语言

AL 语言是由 Dynamics 365 Business Central 开发团队创建的,它是为小型单租户个性化和复杂的垂直解决方案(通过在线 Dynamics 365 Business Central AppSource 市场部署)开发应用程序的官方 Visual Studio Code 扩展。

它可以通过两种不同的方式进行部署:

  • 直接作为 Visual Studio Code 市场中的可下载包。

  • 手动安装,作为可安装包(.vsix):

    • 安装包会在创建一个基于官方 Dynamics 365 Business Central 镜像的 Docker 沙箱时分发。

    • 从 Dynamics 365 Business Central 本地 DVD 下载。

要直接开始使用 AL 语言,只需通过以下简单步骤从市场中下载它:

  1. 启动 Visual Studio Code。

  2. 点击扩展视图栏。

  3. 在搜索框中输入 Dynamics 365 Business Central。

  4. 选择 AL 语言。

  5. 点击安装,并在安装完成后按要求重新加载 Visual Studio Code。它会显示以下 AL 语言扩展:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/ms-ms-dyna365/img/c45e562c-0b5f-43a5-a69c-693260ebbcf1.png

AL 语言的版本号,也称为开发版本,会显示在标题旁边。在前面的截图中,AL 语言开发版本(或运行时)是4.0.182565

开发版本非常重要,因为新语言功能和增强功能通常不会回移植到旧版本中,因此它们可能已经过时,并且与更新的 Dynamics 365 Business Central 平台更新不兼容。

AL 开发者应始终选择最新的 AL 语言开发版本,以便受益于最新的增强功能和稳定性特性。

AL 语言的开发模型涉及创建、编辑和组织具有典型 .al 扩展名的平面文本文件。简而言之:AL 语言开发只是基于文件夹和文件的。

值得一提的是,Visual Studio Code 中的术语将根文件夹称为工作区。AL 语言根文件夹代表扩展的源代码容器。因此,AL 语言根文件夹也被称为 Visual Studio Code 开发工作区。

创建任何类型的扩展时,工作区由以下项目组成:

  • launch.json 文件

  • app.json 文件

  • 符号文件

  • .al 对象文件(如表、页面、报告和代码单元)

  • 补充文件(如 WebService.xml 文件、.bmp 格式的扩展徽标文件和 permissions.xml 文件)

本书及后续章节将更深入分析 AL 语言对象和补充文件。现在我们将重点讨论应用程序开发的核心部分:launch.jsonapp.json 和符号文件。

launch.json

该文件存储在扩展工作区的名为 .vscode 的子文件夹中,主要确定下载和上传 AL 语言命令的具体参数设置。

下表显示了下载和上传 AL 命令:

下载命令 上传命令 AL: 下载符号 AL: 发布 (F5) AL: 下载源代码 (F7) AL: 发布并在设计器中打开 (F6) AL: 无调试发布 (Ctrl + F5) AL: 快速应用发布 (Alt + F5) AL: 快速应用发布无调试 (Ctrl + Alt + F5)

它还仅用于建立连接,如 AL:调试无发布(Ctrl + Shift + F5)命令,或启动特定的调试功能,如 AL:打开事件记录器。事件记录器功能将在第九章《调试》中进行介绍。

launch.json 文件是一个 JSON 数组,可能包含不同的 JSON 值,每个值代表一组针对不同部署目标的属性:本地部署或 SaaS。属性可能是必需的,也可能是可选的,具体取决于目标部署。

下表显示了 launch.json 属性:

属性 必需 部署类型 描述 Name 是 所有 在调试器窗口中显示的名称,用于识别启动参数集。默认值:发布到您的服务器(本地部署),发布到微软云(SaaS)。 Type 是 所有 常量值:alRequest 是 所有 常量值:launchstartupObjectType 否 所有 发布后运行的对象类型:表或页面。 startupObjectId 否 所有 与 StartupObjectType 一起使用。定义要运行的对象 ID。 tenant 否 所有 AAD 租户(SaaS)或租户名称(具有多租户的本地部署)用于连接、提取符号和/或发布应用程序包。 sandbox 否 在线 在为同一 AAD 租户创建多个在线沙盒时,指定沙盒名称。 breakOnError 否 所有 指定当发生错误时调试器是否应停止。默认值:truebreakOnErrorWrite 否 所有 指定调试器是否应在记录更改(插入、修改和删除)时停止。默认值:falseschemaUpdateMode 否 所有 确定数据同步模式。Synchronize:这是默认值。如果该扩展已经部署了数据,则会保留现有数据并且不被删除。扩展的元数据将与现有的元数据进行同步(如果存在)。Recreate:清除之前的元数据(通常是表和表扩展),并从头开始使用新的元数据。ForceSync:强制同步架构。由于可能导致数据丢失,应极其小心使用此选项。 DependencyPublishingOption 否 所有 此参数在 Dynamics 365 Business Central 2019 年秋季更新中引入。适用于多个依赖应用从同一根文件夹加载的复杂环境。可能的值如下:Default:启用所有依赖应用的重建和发布。Ignore:不进行依赖发布。应谨慎使用此选项,因为它有可能破坏现有的相互依赖的解决方案。Strict:如果有任何已安装的扩展依赖于启动文件夹,发布将失败。 Server 是 本地部署 服务器名称。默认值:http://localhostserverInstance 是 本地部署 Dynamics 365 Business Central 服务器服务名称。 authentication 是 本地部署 身份验证类型:Windows 或用户密码。撰写时,AAD 不支持本地部署,并且它是在线部署的默认且唯一值。 Port 否 本地部署 Dynamics 365 Business Central 端口号。默认值:7049applicationFamily 否 AppSource 用于为 AppSource 开发嵌入式扩展。该标签用于 Microsoft 判断目标升级操作,如果在租户中部署了特定的 AppSource 扩展。 launchBrowser 否 所有

指定在发布扩展时是否启动浏览器。

|

enableLongRunningSqlStatements 否 所有

启用在调试时显示长时间运行的 T-SQL 语句。此功能计划支持本地部署和在线沙盒环境。

|

enableSqlInformationDebugger 否 所有 启用获取 T-SQL 查询信息的功能。此功能计划支持本地部署和在线沙盒环境。

如果你在 JSON 数组中设置了多个值,当执行上传或下载 AL 语言命令时,将提示你选择一个定义在 JSON 数组中的参数集名称。

以下截图是 launch.json 文件的示例:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/ms-ms-dyna365/img/fce6197b-48ec-4bbf-9e6f-995eb2dc5204.png

这显示了带有两个参数设置值的文件。

app.json

通常存储在扩展工作区的根文件夹中,它代表了用 JSON 编写的应用清单。在 JSON 文件中,包含了引用基础和系统应用的参数,以及平台和运行时的定义。

在为 Dynamics 365 Business Central 开发时,必须充分理解这些术语。

系统和基础应用

在 2019 年秋季更新中,微软将所有遗留的 C/AL 代码转换为 AL 对象。目前,庞大的应用单体已经被拆分为两个应用:

  • 系统应用:大约包含 200 个对象。

  • 基础应用:根据本地化版本的不同,它包含 6,000 到 8,000 个对象。

要扩展这些应用,需要在 app.json 文件中将其作为依赖项引用,并通过 AL: Download symbols AL 语言命令将其符号拉取到本地或在线沙盒中。

当拉入 .alpackages 文件夹时,它们通常通过主版本号、次版本号、构建号和修订号来引用,并且这一点反映在下载的符号名称中(例如,Microsoft_System Application_15.0.36560.0Microsoft_Base Application_15.0.36626.36918)。

主要版本号通常对应于 Dynamics 365 Business Central 的主要更新发布。

2019 年 10 月(或 2019 年秋季)发布更新是主要版本 15。2020 年春季(或 2020 年 4 月)发布的更新将是主要版本 16,以此类推。

次版本号通常对应于次要更新。2019 年 11 月的更新 1 是次版本 15.1,2019 年 12 月的更新 2 应该是次版本 15.2,以此类推。

构建号是一个递增的数字,每当有更改提交到与功能增强或修复相关的分支时,微软就会增加该数字。

在开发扩展时,必须了解 app.json 文件中 dependency 参数定义的所需系统和应用对象级别的最低要求。

平台

平台表示 Dynamics 365 Business Central 平台组件(客户端、服务器、Web 服务器等)的最终编译结果。

它以与应用程序相同的标记显示。应用程序和平台构建通常有不同的构建号,因为平台代码更改和应用程序代码更改遵循不同的编译路径,最终会合并在一起。

在针对平台开发时,必须了解文件和 API 的最低要求,以便能够利用它们暴露的特性、属性和功能,避免应用程序出现不可预测的行为。

运行时

运行时表示 Dynamics 365 Business Central AL 语言扩展文件的最终编译结果。

该标记法更简洁,由主要版本号、次要版本号和构建版本组成。例如,2018 年春季更新(或 2018 年 4 月更新)命名为主版本 1,而 2018 年秋季更新(或 2018 年 10 月更新)是版本 2,以此类推。当前针对 Dynamics 365 Business Central 2019 年秋季更新的主要版本是版本 4。

在开发扩展时,您可以在 app.json 文件中定义应用程序的目标运行时版本。这将启用或禁用不同的功能集,这些功能集不能成为目标平台部署的一部分,AL 语言扩展的运行时将对此进行检测。

以下表格显示了 app.json 属性:

属性 必需 描述 Id全局唯一标识符GUIDName 是 扩展名称。 Publisher 是 发布者名称。 Version 是 扩展包的版本(例如,1.0.0.0)。 Brief 否(对于 AppSource 是是) 扩展的简短描述。 Description 否(对于 AppSource 是是) 扩展的长篇详细描述。 privacyStatement 否(对于 AppSource 是是) 隐私声明的 URL。 EULA 否(对于 AppSource 是是) 应用的许可条款和条件的 URL。 Help 否(对于 AppSource 是是) 应用帮助台支持的 URL。 url 否(对于 AppSource 是是) 扩展包主页的 URL。 Logo 否(对于 AppSource 是是) 从扩展根目录到应用 logo 的相对路径或完整路径 Dependencies 是 其他扩展的依赖项列表。从 2019 年秋季更新开始,必须至少引用系统应用程序和基础应用程序扩展。 Screenshots 否 应用截图的相对路径或绝对路径。 Platform 是 支持的最低平台版本(例如,15.0.0.0)。 idRanges 是 应用对象 ID 范围或对象 ID 范围的数组。 showMyCode 否 在调试时启用查看扩展源代码和/或从扩展管理页面下载源代码。默认值:falseTarget 否 默认值:Cloud。与 Cloud 相同字体的扩展。它是 Target 选项的两个可能值之一(新版本为 Cloud,旧版本为 Extension)。这两个值是 Dynamics 365 Business Central SaaS 所允许的唯一值。如果需要将扩展定向到本地部署,请将该值设置为 OnPremInternalhelpBaseUrl 否 扩展的在线帮助的 URL。 contextSensitiveHelpUrl 否(对于 AppSource 是是) 针对 AppSource 扩展的上下文敏感帮助的 URL。 supportedLocales 否 应用支持的本地语言的逗号分隔列表。 features 否 可由编译器启用的预览版可选特性。例如,TranslationFile。将此参数标记添加到特性中时,会在扩展文件夹中生成一个名为Translations的目录,并且会生成一个包含所有扩展对象中使用的标签的.xlf翻译文件。 Runtime 否 扩展所针对的最低运行时版本。

以下截图是一个app.json文件的示例:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/ms-ms-dyna365/img/b7680dcb-1845-4959-9cba-e5a1849f1386.png

有了这些信息后,我们应该能够掌握应用程序配置文件,并根据运行时版本对其进行调整。在下一部分,我们将介绍符号并解释它们在扩展开发中的至关重要性。

理解符号

就像在所有其他语言中一样,符号表示对标准对象、属性和函数集合的引用。它们本身就是一个特殊的扩展文件,采用典型的.app命名规则,用于在编译时保持对象引用的一致性,同时还填充有效的 IntelliSense 条目。

符号通常以 JSON 格式存储在数据库中的 BLOB 字段中,每个对象记录都有一个。值得一提的是,在多租户环境中,Object Metadata表是应用程序数据库的一部分,因此在客户租户数据库中不会存储系统符号或元数据,只有数据。

在 Dynamics 365 Business Central 中,符号已经预先加载到应用程序数据库中,并且可以将它们分为两类:

  • 标准符号

  • 扩展符号

在 2019 年秋季更新之前,标准应用程序符号都是通过微软使用 CSIDE 开发环境对标准遗留对象进行特殊编译生成的。对于本地版本,情况也是如此:符号是异步生成的,或者可以通过 PowerShell 脚本作为常规扩展导入。

标准应用程序符号存储在Object Metadata表中的 Symbol Reference BLOB 字段中。

通过阅读以下官方参考文档,可以了解更多关于此主题的信息:

docs.microsoft.com/it-it/dynamics365/business-central/dev-itpro/developer/devenv-running-cside-and-al-side-by-side

下表展示了标准符号。在 2019 年秋季更新之前,了解这些符号及其重要性对成功编译和部署任何类型的扩展至关重要:

应用程序 包含 CSIDE 对象设计器中描述的所有应用程序对象的符号,除了 2000000004 到 2000000199 ID 范围内的系统表和标准测试工具对象。在本地版本或 Docker 沙盒中,如果你正在修改标准遗留对象,你必须选择通过 CSIDE 开发环境(重新)生成符号,正如以下博客文章中所述:在现代开发环境中使用 Microsoft Dynamics NAV 2018 生成符号。在升级后的本地版本中,来自早期版本的符号必须从标准本地数据库(或产品 DVD)中提取,导入到升级数据库中,并重新生成,正如以下博客文章中所述:在新建或升级数据库中导入符号与 Microsoft Dynamics NAV 2018。 系统 包含 2000000004 到 2000000199 ID 范围内的系统表符号,也包括虚拟表定义。系统和虚拟表结构无法通过扩展进行修改。系统和虚拟表符号无法重新生成。因此,如果你正在开发扩展,它们永远不应该在 CSIDE 开发环境中进行任何更改。 测试 包含应用程序测试工具对象的符号。标准应用程序测试工具对象的符号无法重新生成。开发人员应创建自己的测试对象。因此,在现代开发环境中进行 SaaS 部署时,它们永远不应在 CSIDE 开发环境中进行任何更改。

每当你扩展一个应用程序时,你总是需要确保适当的符号到位。你可以通过两种方式实现这一点:

  • 连接到沙盒环境,运行命令面板(Ctrl + Shift + P),然后输入并选择AL: Download Symbols

  • 从其他地方(例如产品 DVD,用于本地部署)下载所需的符号,并将其存储在定义的符号存储目录中。

对于本地部署,您将在 Dynamics 365 Business Central 2019 年春季版产品 DVD 中找到 System.appTest.app 符号,路径为:\\ModernDev\\program files\\Microsoft Dynamics NAV\\140\\AL Development Environment。在 Dynamics 365 Business Central 2019 年秋季版 DVD 中,您只会在以下路径找到 System.app\\ModernDev\\program files\\Microsoft Dynamics NAV\\150\\AL Development Environment。自 2019 年秋季更新以来,AL 语言运行时不再自动下载应用程序和测试符号,且这些符号不再需要存储在数据库内,因为所有属于应用程序的对象,包括 Test Toolkit 中的对象,已经转化为 AL 对象。这些 AL 对象现在是标准扩展包的一部分。扩展包本身就包含符号。

如果您有一个多用户环境,且开发人员在同一个暂存租户上工作,您可以考虑通过命令面板下载符号一次,然后为所有用户设置一个公共的符号存储路径。这样可以避免每次都下载相同的符号集,从而提高开发生产力。

默认的符号存储路径可以通过以下快捷键之一进行更改:

  • 从菜单栏中,选择“文件”(Alt + F)| “首选项”(P)| “设置”(S),然后选择 AL 语言设置。

  • 使用设置快捷键(Ctrl),然后选择 AL 语言设置。

要更改的参数是 Al: Package Cache Path,其默认值设置为相对路径 ./.alpackages

或者,您可以运行命令面板(Ctrl + Shift + P),输入并选择“Preferences: Configure language specific settings…”,然后选择 AL。settings.json 文件将打开,您可以在其中添加或更改 al.packageCachePath 参数的值。下图显示了 AL 设置符号路径在更改为存储位置时的情况:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/ms-ms-dyna365/img/c14ca852-89f4-4fd1-865c-7c4319f350eb.png

本章后续将讨论其他 AL 语言配置设置。

结合系统应用扩展、基础应用扩展和标准符号,您的扩展可能还依赖于其他自定义或第三方扩展。然后,这些扩展应该会发出符号,您应该能够在调用 AL:从命令面板下载符号时从应用程序数据库中下载这些符号。

扩展符号存储在 NAV App 表的 Symbols BLOB 字段中。

要指定您的扩展依赖于另一个扩展,您必须在 app.json 文件中填充相关的 JSON 数组参数。下面是一个依赖于两个其他应用的扩展在 app.json 文件中的参数示例:

 \"dependencies\": [ { \"appId\": \"63ca2fa4-4f03-4f2b-a480-172fef340d3f\", \"publisher\": \"Microsoft\", \"name\": \"System Application\", \"version\": \"15.0.0.0\" }, { \"appId\": \"437dbf0e-84ff-417a-965d-ed2bb9650972\", \"publisher\": \"Microsoft\", \"name\": \"Base Application\", \"version\": \"15.0.0.0\" }, { \"appId\": \"99ddd910-3aa8-4c3e-936c-be20edeaf777\",  \"name\": \"Preferred Wine Basic\" \"publisher\": \"Tacconi Inc.\" \"version\": \"1.0.0.0\" }, { \"appId\": \"77ddd910-3aa8-4c3e-936c-be20edeaf888\", \"name\": \"Preferred Wine Tools\", \"publisher\": \"Tacconi Inc.\", \"version\": \"2.1.0.0\" } ],

如果你已经从 Cloud Ready Software 安装了 CRS AL Language Extension 工具箱(marketplace.visualstudio.com/items?itemName=waldo.crs-al-language-extension),你可以输入 tdependency 来启用代码片段,轻松编辑该参数的每个 JSON 数组元素。这将加快你的编码速度,防止语法错误。在本章最后一节中,我们将讨论标准和自定义代码片段的功能。

依赖扩展的版本参数表示编译器接受符号的最低要求。换句话说,低于报告版本的依赖扩展符号不被认为是有效的,无法下载或编译。

符号内部

符号是多个文件的压缩(.zip)操作的结果,这些文件由 AL Language 扩展使用。为了展示其内部原理,只需使用最常见的解压工具(例如 7-zip)在将 .app 包重命名为 .navx 扩展名后提取其内容。

以下表格显示了基础应用程序扩展的标准符号组件(文件和目录):

文件名 描述 [Content_Types.xml] 指定包的内容:XML 和 JSON 文件。 MediaIdListing.xml 指定扩展标志文件名及其 ID。 navigation.xml 包含部门菜单的条目。 NavxManifest.xml 它将报告标准符号或扩展的清单。基础应用程序符号的最相关参数如下:- version:标识 JSON 文件的应用程序版本(如 15.0.36626.36675)- platform:目标推荐的与这些符号兼容的主要平台版本(如 15.0.0.0)- runtime:建议用于这些符号的运行时版本(如 4.0)系统符号通常只指定版本和运行时。 SymbolReference.json 包含所有 AL 对象的 JSON 格式引用。这些 JSON 文件被 AL Language 扩展广泛使用,用于在编译/构建应用程序包时保持引用完整性,并启用所有与 IntelliSense 相关的功能。基本上,它的结构是一个数组,包含有效 AL 对象参数的列表,如下所示:\"Tables\": [],`` \"Codeunits\": [],`` \"Pages\": [],`` \"PageExtensions\": []对于这些对象元素,每个都有指定的字段、属性、函数等。

符号 JSON 文件不能被篡改/更改以手动生成或修改符号文件。

接下来,我们还将看看不同目录的作用:

目录名称 内容描述 addin 控制插件定义。 layout RDL 和 DOCX 报告布局。 logo 扩展标志。 ProfileSymbolReferences 配置文件符号和相关页面自定义的符号。 src AL 文件。其内容通常用于在调试时显示代码。 Translations XLIFF 格式的翻译文件。

符号是扩展验证机制的核心,正如之前的表格所示,它们还执行代码(如果在扩展的app.json文件中将showmycode参数设置为 true 的话)。

基于 AL 符号,你可以在 Visual Studio Code 市场中找到非常有用的扩展,这些扩展专门针对 AL 开发环境。

最常用的配置项如下:

  • Marton Sagi 的 AL 对象设计器

  • Andrzej Zwierzchowski 的 AZ AL 开发工具/AL 代码大纲

两者都非常易于使用,并且对检查符号及其内容非常有用。

在了解了符号之后,我们已经完成了构建应用所需的主要内容的概述。接下来,让我们看看 AL 语言扩展配置,了解如何配置它们以创建更高效的开发环境。

理解 AL 语言扩展配置

可以通过快捷键 Ctrl+ 来轻松查看常规设置和每个工作区设置。会弹出一个直观的菜单,选择“扩展 | AL 语言扩展配置”,即可列出一系列配置参数。以下截图显示了 AL 语言扩展配置参数:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/ms-ms-dyna365/img/e292a06b-c8f1-4464-b78c-0731b5fcc917.png

基本上,这些配置值保存在一个名为settings.json的文件中。

以下是常见配置项的描述和值:

  • 对于以下路径参数:

    • \"al.packageCachePath\": \"./.alpackages\":可以将默认值更改为本地文件夹或多开发者环境下的共享文件夹。它表示存储和查找符号的路径。

    • \"al.assemblyProbingPaths\": [\"./.netpackages\"]:这个参数在编译扩展时至关重要,特别是当存在外部程序集引用时。它的数据类型是 JSON 数组,因此开发者需要指定一个以逗号分隔的路径列表,表示程序集存储的位置。

    • \"al.ruleSetPath\": null:如果开发者希望提供自定义的标准代码分析器规则覆盖,可以使用此设置。它将在第九章 调试中进行详细讨论。

  • 对于以下代码分析器参数:

    • \"al.enableCodeAnalysis\": false:此设置用于启用代码分析,具体内容将在第九章 调试中详细讨论。在大型项目中,若有数千个对象,建议关闭此功能,以避免在编码或编译过程中出现性能问题。

    • \"al.codeAnalyzers\": []:这是代码分析器的类型。其详细内容将在第九章 调试中进一步探讨。

    • \"al.enableCodeActions\": false:启用代码操作,如自动将多个if语句转换为CASE语句或拼写检查。默认情况下该功能为禁用状态。

    • \"al.backgroundCodeAnalysis\": true:默认启用。在大型项目中,这可能会对性能造成严重影响,建议在此类场景中关闭此功能。

  • 对于以下编译参数:

    • \"al.compilationOptions\": {\"generateReportLayout\": true, \"parallel\": true}:用于指定在编译时是否生成报告布局(如果报告布局不存在),以及是否对包进行串行或并行构建。

    • \"al.incrementalBuild\": false:在复杂的扩展开发环境中,如果从根文件夹加载多个扩展文件夹,则此参数指定是否从引用的项目中进行引用解析,而不是从存储在包缓存路径中的符号中进行解析。将此参数切换为 true 会在此类场景中提高性能。

  • 对于以下服务日志参数:

    • \"al.editorServicesLogLevel\": null:这对于调试编译报告中未处理的错误或崩溃的情况非常有用。日志可能包含错误,甚至详细描述发生在后台的过程。将会在第九章中更深入地讨论,调试部分。

    • \"al.editorServicesPath\": \"bin/\":如果启用了服务日志,则决定日志路径。

  • 对于以下浏览器参数:

    • \"al.browser\": \"Edge\":选择首选浏览器,从 Visual Studio Code 启动 Dynamics 365 Business Central 应用程序。选项包括 SystemDefault、Edge、Chrome 或 Firefox。如果安装了多个浏览器,则此选项非常有用。

    • \"al.incognito\": false:选择以正常会话启动浏览器,该会话存储现有的凭证,或使用私人/隐身浏览。

在探索了开发扩展所需的核心设置之后,让我们分析一下 AL 语言提供的最佳代码编辑功能之一:代码片段。

精通 AL 语言代码片段

安装 AL 语言扩展后,Visual Studio Code 中提供了 AL 语言标准代码片段。这些片段会在你在代码编辑器中输入时触发,你可以通过方框前缀符号识别它们。

通常,它们以字母t开头,后跟一个有意义的名称,用以描述代码片段的内容,例如ttabletpage。悬浮提示显示代码片段的预览。

以下截图展示了一个 if-then-else 条件语句的标准代码片段:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/ms-ms-dyna365/img/1623b328-1ca2-46c8-b716-0bbf99fa40da.png

请注意,如果代码片段包含变量名或代码标识符,它们可能会被高亮显示,提示你应该为其指定不同的名称,并且它们充当某种占位符。当你重命名一个被高亮的标识符时,所有该标识符的出现位置也会被重命名,这使得代码片段的使用非常灵活。这不仅会减少编码时间,避免写或复制粘贴重复的语句,还能使用开发者可能忽略的复杂结构语法。

可以直接从 Visual Studio 市场下载由其他开发者制作的代码片段,形式为扩展。通常,许多扩展程序会扩展 AL 语言的支持,并附带一系列自己的代码片段。

一个典型的例子是免费的 CRS AL 语言扩展。

除了几个非常有用的开发者工具外,这个扩展还实现了一组与现有标准片段集成并丰富它们的 AL 代码片段。目前,它实现了 68 个额外的 AL 代码片段,并且随着每次扩展更新,列表还在不断增长。

以下截图显示了如果你在 .al 文件中输入 CRS 时,所有可用的额外代码片段:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/ms-ms-dyna365/img/2063ec22-341a-43e3-ae8d-9be56b4556c4.png

另一个在编码时搜索代码片段的方法是运行命令面板 (Ctrl + Shift + P),然后输入 snippet 或 insert snippet 来调出一个下拉列表,显示可用的 AL 代码片段。

以下截图显示了来自命令面板的 AL 代码片段下拉列表:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/ms-ms-dyna365/img/438bb2db-46b4-4c30-aa5a-c0d6aeaaee32.png

如果你仍然没有在市场中找到对你有用的代码片段,使用 Visual Studio Code 你也可以手动从零开始添加新的代码片段。要做到这一点,你需要点击菜单栏并进入 文件 (Alt + F) | 首选项 (P) | 用户代码片段 (S + S).

快捷键序列 Alt + FPSSEnter 可以直接将你带到那里,而无需使用鼠标。

然后,你可以选择是为所有语言创建一个全局代码片段,还是为当前工作区创建一个本地代码片段,或者为特定目标语言创建一个片段。在这个例子中,我们将选择从语言列表中选择 al (AL),创建一个新的代码片段以供 AL 语言文件使用。

以下截图显示了创建特定代码片段时的可用选项:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/ms-ms-dyna365/img/e66e468e-6db6-4a4d-9973-9f74ba95e6ab.png

如果你启用了面包屑功能,可能已经注意到一个特定的配置文件处于编辑模式,用于自定义 AL 语言代码片段。通常,这个文件叫做 al.json,并存储在以下位置:

C:\\Users\\\\AppData\\Roaming\\Code\\User\\snippets

每个代码片段由一个独特的名称定义,并由三个元素组成:

  • 前缀:用于在编辑器中搜索并触发代码片段

  • 主体:粘贴到编辑器中的部分

  • 描述:对代码片段功能的详细描述

在代码块内,你可以使用特定的语法来启用占位符:

  • $1$2$3$n 用于通过按下 Tab 键来移动代码片段中的光标位置。

  • $0 用作最终的光标位置。

  • ${1:labelX}${2:labelY}${3:labelZ} 用作占位符。具有相同 ID 的占位符会相互关联,从而启用多个光标功能。

现在,我们将通过一个简单的示例进行演示。

假设你想在对象顶部添加一个标准的代码头块,就像在旧版设计器(CSIDE 开发环境)中一样,并且你需要一个智能的方式,在每个对象上快速且重复地实现这一功能。

最简单的解决方案是创建一个特定的自定义代码片段,在每次新建对象文件时调用,如下所示:

  1. 将以下代码添加到 al.json 文件中并保存:
{ \"Create standard comment block\": { \"prefix\": \"tcomment (Custom)\", \"body\": [ \"//\", \"// ${1:YY.MM.DD} Initialization\", \"// ${1:YY.MM.DD} ${2:Modification Description}\", \"//\" ], \"description\": \"Standard header comment block\"}}

你可以通过简单地进入菜单栏并选择 文件(Alt + F)| 自动保存(U)来启用惊人的自动保存功能。自动保存菜单项旁会出现一个勾选标记。另一种方法是运行命令面板(Ctrl + Shift + P),然后输入 File: Toggle Auto Save(或者输入其中一部分并从下拉列表中选择该条目)。

  1. 在你的扩展中创建一个新文件,并将其保存为 .al 扩展名(例如,MyCodeunit.al)。光标应该会自动定位到文件的第一行和第一列。

  2. 开始输入 tcomment,IntelliSense 将检测到你自定义代码片段的存在。选择它。

  3. 光标将定位到第一个占位符元素。只需输入当前日期(格式为 YY.MM.DD),然后按 Tab。你可能会注意到,由于两个占位符共享相同的 ID,它们会一起编辑,从而启用多个光标功能。

  4. 现在,是时候写下与对象描述相关的有用信息,说明它的用途。

以下截图展示了带有多个光标的自定义注释块代码片段的实际应用:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/ms-ms-dyna365/img/218bb777-f46d-4d80-8416-6fd7f3941407.png

这些代码片段使理解 Visual Studio Code 变得更加简单。试试看,掌握它们吧!

总结

Visual Studio Code 是一个以代码为中心的工具,开箱即用支持多种语言,提供诸如语法着色、分隔符匹配、代码块折叠、多光标、代码片段、IntelliSense 等编程功能,还有更多功能。

通过安装 AL 语言扩展,这个现代化的开发环境已完全设置好,成为初学者和有经验开发者的应用沙盒。在本章中,我们释放了一些技巧和窍门,使你能够熟练掌握开发人员日常工作,快速为 Dynamics 365 Business Central 创建现代应用。

接着,我们开始学习这个现代开发环境所提供的强大编码功能。所有这些学习结束后,是时候在本书中看到 AL 语言的实际应用了。但是,在进入结构化和高级扩展开发之前,了解如何实现和维护一个沙箱/预发布环境是很重要的。这正是我们在下一章要做的内容。

第三章:在线和基于容器的沙盒

Dynamics 365 Business Central 允许我们为开发和测试目的设置沙盒。对于这些沙盒,有两种通用选项:在线沙盒(基于 SaaS)和基于 Docker 的沙盒(自部署)。

在线沙盒创建非常简单,因为它们作为服务运行,与 Dynamics 365 Business Central 的生产环境相同。唯一的要求是已有的生产租户。

基于 Docker 的沙盒基于 Docker 容器,可以在 Azure 或本地运行。

本章我们将覆盖以下主题:

  • 创建在线沙盒

  • Docker 镜像和容器的基础知识,以及如何使用它们

  • 设置本地 Docker 环境

  • 掌握 navcontainerhelper PowerShell 工具

  • 为你的开发目的选择合适的 Docker 镜像

  • 创建你自己的 Docker 镜像

创建在线沙盒

在订阅试用租户或直接购买 Dynamics 365 Business Central 时,你也可以创建在线沙盒环境。

你可以通过两种方式创建在线沙盒:通过生产环境客户端和/或通过 Dynamics 365 Business Central 管理中心。

从生产环境创建时,搜索 (*Alt *+ Q) sandbox,然后选择沙盒环境(预览版):

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/ms-ms-dyna365/img/e6b3dc6b-6bca-4200-a80d-94fd8e70de9e.png

然后你将被提示创建一个新的沙盒环境,或者打开或重置现有的沙盒。如果没有沙盒且你选择打开或重置,将创建一个新的沙盒。使用生产环境客户端创建的在线沙盒具有以下属性:

  • 它们默认命名为 sandbox,并且也能在 Dynamics 365 Business Central 管理中心中看到。

  • 它们不包含任何客户数据,仅包含来自标准演示/评估 Cronus 公司的数据。

在订阅在线沙盒租户时,仔细阅读微软免责声明非常重要,值得一提的是,此功能仍标记为预览版:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/ms-ms-dyna365/img/8e6ad481-0c9e-4b72-96da-8328f05cbb65.png

你还可以从 Dynamics 365 Business Central 管理中心创建最多三个沙盒环境。使用适当的凭证,通过支持的浏览器登录 https:\\businesscentral.dynamics.com\\GUID\\Admin,其中 GUID 是你环境的租户 ID。

以下是管理中心中的样子:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/ms-ms-dyna365/img/a85a3108-4061-46d4-8907-28f1cf5f4d50.png

点击 新建 按钮,然后为新的在线沙盒指定一个有效的名称。勾选复制生产数据的选项:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/ms-ms-dyna365/img/0e7e50d0-0ea4-41b1-9fbe-9dc1fc807f87.png

稍等片刻,你的沙盒将会启动并运行,带有生产数据的副本,准备好进行测试和开发任务。

在线沙盒的优缺点

根据微软的免责声明,在线沙盒仍然是预览功能,我们建议仅将其用于演示目的或临时开发活动。在线沙盒具有以下特点:

  • 它们的支持优先级不同于生产环境。

  • 租户是创建在 Azure SQL 数据库的 S 等级池中,这些池的性能不如生产环境中的 P 等级池。

  • 它们仍然被标记为预览版,因此经常会发生变化。

  • 在升级过程中,目前所有每个租户的扩展都将被卸载,您/您的 CSP 合作伙伴需要重新安装它们。

您可以通过阅读以下文章了解更多背景信息:

  • demiliani.com/2019/01/24/dynamics-365-business-central-tenant-upgrade-extensions-disappeared-in-sandbox-environment/

  • demiliani.com/2019/03/14/dynamics-365-business-central-online-sandbox-makes-you-crazy-maybe-remember-these-points/

对于专业开发,基于容器的沙盒更为合适,我们鼓励您在开发 AppSource 或每个租户扩展时,在公司中使用 Docker 容器沙盒。

从在线生产环境中,您也可以搜索(Alt + Q)沙盒并点击沙盒环境(容器),轻松设置离线本地或 Azure 托管的 Docker 容器沙盒。

您可以通过demiliani.com/2018/03/29/d365bc-container-sandbox-environment/了解更多信息。

让我们进入下一部分,学习如何使用基于 Docker 的环境。

引入 Docker

如果选择使用自部署的沙盒,它们将基于 Docker。Docker 是领先的跨平台软件容器环境。由于本书是关于 Dynamics 365 Business Central 的,本节将简要介绍 Docker,但如果您想了解更多,有关 Docker(docs.docker.com/)和微软(docs.microsoft.com/en-us/virtualization/windowscontainers/about/index)的官方文档中有很多优秀的学习资源,都是非常好的起点。

Dynamics 365 Business Central 在 Windows 上运行,因此当您查找 Docker 文档时,请确保它是针对 Windows 的。虽然大部分 Docker 是平台无关的,但仍有一些特定平台的部分内容。

为了跟随接下来的内容,你需要了解以下 Docker 基础知识:

  • Docker 镜像就像一个预构建的模板,包含运行所需的最少操作系统二进制文件、库和应用程序二进制文件。镜像可以通过名称来识别,例如 Business Central / Sandbox。可以通过标签指定确切的镜像版本。例如,1910-cu1-de 表示 2019 年 10 月发布1910)、CU 1cu1)、德语版本de)。

  • Docker 容器是镜像的一个实例,具有不可变的基础(镜像中的文件)以及在其上进行的更改。容器不是 虚拟机VM)。它没有 GUI 或任何你可以通过 远程桌面协议RDP)连接的内容。

  • Docker 主机是一个运行容器的(物理或虚拟)机器。

  • Docker 仓库是你和其他人可以上传(推送)和下载(拉取)镜像的地方。具体来说,镜像可以从属于该注册表的仓库中下载。

所有 Dynamics 365 Business Central Docker 镜像都可以通过 Microsoft 容器注册表获得,你可以在 mcr.microsoft.com 的 business central 仓库中找到它。它将被称为 sandboxon-prem,因此,从 Dynamics 365 Business Central 本地镜像拉取的典型地址是 mcr.microsoft.com/businesscentral/onprem:1810-cu5-de。

对于新版本和即将发布版本的预览,还有一个特殊的仓库 bcinsider.azurecr.io,但你需要凭证才能访问它。Microsoft 通过 Ready to Go! 程序提供这些凭证,你可以在协作平台上找到它们 (docs.microsoft.com/en-us/collaborate/)。

用于创建和运行 Dynamics 365 Business Central 镜像的脚本是开源的,可以在 github.com/Microsoft/nav-docker 上找到。

还值得注意的是,尽管这些镜像被称为 business central,但它们还包含一个 SQL Server 数据库,一个用于 Web 客户端 的 IIS,以及默认的文件共享功能。

使用 Docker 时的一些基础机制

在接下来的章节中,我们将使用几个涵盖大多数实际场景的机制。让我们逐一了解它们。

环境变量

环境变量是一种在 Docker 容器启动时进行参数化的方式。Dynamics 365 Business Central 镜像理解许多环境变量,例如用于设置认证类型、用户名和密码,或设置你希望将 Business Central 服务层连接到的 SQL 服务器和数据库。环境变量通过 -e 参数设置。如果你需要设置多个环境变量,可以使用多个 -e 参数:

-e auth=Windows -e databaseserver=sql -e databasename=cronus

没有关于所有环境变量的列表,你可以使用这些环境变量来根据你的需求配置 Dynamics 365 Business Central 容器,但用于设置这些变量的脚本是一个不错的起点,并且这些变量的名称可以让你大致了解它们的作用。你可以在 github.com/Microsoft/nav-docker/blob/master/generic/Run/SetupVariables.ps1 找到这个脚本。

使用卷,你可以将 Docker 主机上的文件夹映射到容器中,例如,为容器提供访问运行解决方案所需的二进制文件或其他文件的权限。

如果你没有使用卷,并且删除了一个容器,那么你对容器内文件系统所做的所有更改将会丢失,因为它们会与容器一起被删除。

卷通过 -v 参数进行设置,后面跟着主机上的路径,一个冒号,以及容器内部的路径。如果你想将主机上的 c:\\data\\containers 文件夹映射到容器内的 c:\\temp,你可以使用以下命令:

-v c:\\data\\containers:c:\\temp

网络和端口

Docker 让你可以通过不同的方式将容器连接到网络。如果你没有做其他配置,它会使用一个所谓的 NAT 网络。这意味着你的容器将获得一个仅在 Docker 主机上可知的 IP 地址,这也使得容器在主机上是可访问的。作为替代方案,你可以创建一个所谓的透明网络,这意味着容器将共享主机的网络连接,并且会尝试使用 DHCP 动态 IP 分配或你配置的静态 IP 地址来获取自己的 IP 地址。如果你有一个名为 transpNet 的透明网络,你可以通过以下命令告诉 Docker 使用它:

--network transpNet

Dynamics 365 Business Central 镜像使用所有标准端口,因此你有 7045-7049 用于 Business Central 服务层服务,443 用于 HTTPS,80 用于 HTTP 的 Web Client,以及 1443 用于 SQL。它们还通过端口 8080 共享一些文件,这个端口被映射到 IIS 后端共享。

如果你不想使用透明网络,但仍然希望将端口暴露到 Docker 主机之外,你可以使用一种叫做端口映射的机制,使用 -p 参数。通过这个参数,你可以告诉 Docker 将容器的某个端口映射到主机上的相同端口或不同端口。如果你想将基于 HTTPS 的 Web Client(监听在端口 443 上)暴露到主机的端口 4443,你通常会使用以下命令:

-p 4443:443

由于 Dynamics 365 Business Central 在知道它监听哪些端口时会运行得更好,最佳方法是包含 -e WebClientPort=4443,这样会让 Web Client 监听该端口而不是标准端口 443。因此,你的端口映射参数将是 -p 4443:4443

Docker 在 Dynamics 365 Business Central 沙盒中的特别有用场景

有一些场景下,使用 Docker 容器非常有意义,可以帮助解决常见的问题。请注意,在撰写本文时,Dynamics 365 Business Central 在 Docker 容器中运行尚不支持生产环境,因此你只能将其用于开发和测试。本文将覆盖的场景如下:

  • 本地可用场景:你希望在本地沙盒或自己的虚拟机上运行沙盒。

  • 集中式可用环境:沙盒提供于一个中央环境中,并由某种操作团队进行管理。

  • 托管在 Azure 虚拟机上的容器:如果你不想或者不能在自己的数据中心拥有虚拟机,你可以使用 Azure 的基础设施即服务IaaS)来托管你的沙盒。

  • Azure 容器实例中的无服务器环境:如果你只想运行容器而不关心 Docker 本身,你也可以使用 Azure 容器实例的平台即服务PaaS)选项。

值得一提的是,还有其他选项,比如Azure Kubernetes 服务AKS)或其他云提供商的产品,但由于 Dynamics 365 Business Central 倾向于与更多微软导向的客户一起使用,而 Kubernetes 最近才开始支持 Windows 容器,因此这里不会讨论这些选项。

Docker 对于持续集成/持续交付CI/CD)流水线中的自动化构建也非常有用。这个主题将在第十一章,与 Business Central 的源代码管理和 DevOps中深入讨论。

使用纯 Docker 命令的本地可用环境

如果你想让使用者完全控制 Dynamics 365 Business Central 沙盒或需要离线使用它们,那么将沙盒放在本地是有意义的。然而,这会要求使用者至少理解 Docker 的基础知识,虽然这并不复杂,但可能不符合你的需求。

你的第一个容器

运行 Dynamics 365 Business Central 沙盒的第一步是安装 Docker。这个过程很简单,并且有相关文档可供参考:docs.docker.com/install/windows/docker-ee/。完成安装后,就可以开始运行你的第一个容器。微软提供了一个非常有用的 PowerShell 模块navcontainerhelper,它简化了容器创建过程。然而,为了帮助你理解底层机制以及 Dynamics 365 Business Central 镜像的工作原理,最好通过几个简单的 Docker 示例来了解。

运行 Dynamics 365 Business Central 沙盒的最基本方式是使用以下命令:

docker run -e accept_eula=y mcr.microsoft.com/businesscentral/sandbox

这只在所谓的进程隔离模式下有效,这允许容器根据需要使用主机资源(如内存)。根据你的配置以及你是否运行的是旧版 Windows 10 或 Docker,你可能会收到一条错误信息,表示容器内存不足。在这种情况下,添加-m 3G作为参数,这将允许容器保留 3 GB 的内存。

有关进程隔离的更多信息,请参阅 docs.microsoft.com/en-us/virtualization/windowscontainers/manage-containers/hyperv-container

请注意,默认情况下,这将基于 Windows Server 2016 拉取镜像。如果你想运行基于 Windows Server 2019 的更小、更快速的镜像,你需要添加一个称为标签的参数;在这种情况下,这个标签将是ltsc2019。更多细节可以在选择合适的镜像部分找到:

docker run -e accept_eula=y mcr.microsoft.com/businesscentral/sandbox:ltsc2019

这指示 Docker 使用指定的镜像(即mcr.microsoft.com/businesscentral/sandbox)运行一个容器。运行容器意味着 Docker 会检查该镜像是否已经被下载(拉取),如果没有,它将拉取镜像。如果已经存在,或者 Docker 已经为你下载了镜像,它将为该镜像创建并启动一个容器。你将看到从主进程输出的内容,显示在你运行该命令的控制台窗口中。

使用-e参数时,你让 Docker 知道你希望在容器内设置accept_eula=y环境参数,这意味着你接受最终用户许可协议EULA)。每当你运行 Dynamics 365 Business Central 沙箱时,这都是必要的。

以下是docker run命令的输出,其中镜像本地不可用:

docker run -e accept_eula=y -m 3G mcr.microsoft.com/businesscentral/sandboxUnable to find image \'mcr.microsoft.com/businesscentral/sandbox:latest\' locallylatest: Pulling from businesscentral/sandbox3889bb8d808b: Already exists…6d7321cdab15: Already exists5c2abed3c0c2: Already exists0bc14e36adef: Pull complete4fd56667f5dc: Pull complete…4dd9d6309b80: Pull completeDigest: sha256:ca99037c70e1eedf21e8472a5d46efeb148dd46a7b16bdf2ddad864e2e4cb97cStatus: Downloaded newer image for mcr.microsoft.com/businesscentral/sandbox:latestInitializing...Starting ContainerHostname is 12cec5da3d89PublicDnsName is 12cec5da3d89Using NavUserPassword AuthenticationStarting Local SQL ServerStarting Internet Information ServerCreating Self Signed CertificateSelf Signed Certificate Thumbprint 857B5A19C68D44BE3368CB96E2AFF6F540C0D957Modifying Service Tier Config File with Instance Specific SettingsStarting Service TierRegistering event sourcesCreating DotNetCore Web Server InstanceEnabling Financials User ExperienceCreating http download siteSetting SA Password and enabling SACreating admin as SQL User and add to sysadminCreating SUPER userContainer IP Address: 172.20.200.44Container Hostname : 12cec5da3d89Container Dns Name : 12cec5da3d89Web Client : https://12cec5da3d89/BC/Admin Username : adminAdmin Password : Fuwu1800Dev. Server : https://12cec5da3d89Dev. ServerInstance : BCFiles:http://12cec5da3d89:8080/al-4.0.192371.vsixhttp://12cec5da3d89:8080/certificate.cerInitialization took 164 secondsReady for connections!

如你所见,日志输出会告诉你在哪里可以访问容器的Web Client和开发服务器服务(用于与 Visual Studio Code 的 AL Language 扩展进行连接)(暂时使用 IP 地址,稍后会详细说明)以及使用的用户名和密码。

拉取新镜像版本

请注意,默认情况下,Docker 不会检查镜像是否有新版本并提示你下载。如果你想确保你有当前版本,可以运行以下命令,它将始终检查是否有更新的镜像:

docker pull mcr.microsoft.com/businesscentral/sandbox

如果有新版本可用,Docker 将会下载它,并输出类似于你之前看到的内容。如果没有新版本可用,你将看到以下信息:

docker pull mcr.microsoft.com/businesscentral/sandboxUsing default tag: latestlatest: Pulling from businesscentral/sandboxDigest: sha256:ca99037c70e1eedf21e8472a5d46efeb148dd46a7b16bdf2ddad864e2e4cb97cStatus: Image is up to date for mcr.microsoft.com/businesscentral/sandbox:latest

我们还可以使用更多环境参数、卷和端口映射,来展示一个更高级的示例,同时使用我们之前介绍的机制:

docker run -e accept_eula=y -e usessl=n -v \"c:\\dev\\addins:c:\\program files\\Microsoft\\Dynamics Business Central\\150\\Service Tier\\Add-ins\\mine\" -p 80:80 –name mycontainer mcr.microsoft.com/businesscentral/sandbox

这实现了以下功能:

  • 它接受 EULA,并通过两个-e参数告诉镜像不要为Web Client使用 SSL。

  • 它使用-v参数将本地文件夹c:\\dev\\addins映射到 Business Central 服务层Add-Ins文件夹中的mine子文件夹。

  • 它使端口80在你的笔记本电脑上作为端口80可用,使用-p参数。你也可以使用-p 8080:80,这会将你笔记本电脑上的端口8080映射到容器上的端口80

  • 它将容器命名为mycontainer,这样你可以轻松地通过--name参数来引用它。

既然我们已经了解了如何运行本地 Docker 环境,接下来让我们看看如何连接到现有的 SQL Server 实例。

连接到现有的 SQL Server

你可以指示容器连接到现有的 SQL Server 和数据库,而不是使用容器内部的 SQL Server,这样容器内部的 SQL Server 也不会启动。如果你想将多个实例连接到同一个数据库,这是必要的,但如果你想在同一主机上运行多个容器,这也很有意义。否则,你将每个容器都运行一个 SQL Server,这将需要大量资源。

在本节中,我假设在你的本地环境中运行着一个名为sqlserver的 SQL Server(无论是否在容器中),并且 Business Central 容器能够访问它。我有一个名为sqluser的 SQL 用户,密码为1SuperSecretPwd!,该用户具有访问该服务器上名为FinancialsW1的 Business Central 数据库的必要权限。对于这种情况,docker run命令将如下所示:

docker run -e accept_eula=y -e databaseServer=sqlserver -e databaseUsername=sqluser -e \"databasePassword=1SuperSecretPwd!\" -e databasename=FinancialsW1 mcr.microsoft.com/businesscentral/sandbox

我们得到以下输出:

Initializing...Starting ContainerHostname is c9658bdbe7f0PublicDnsName is c9658bdbe7f0Using NavUserPassword AuthenticationStarting Internet Information ServerImport Encryption KeyCreating Self Signed CertificateSelf Signed Certificate Thumbprint 87B2FC05A437AFE41966A3E99EFC75A2C2CAD537Modifying Service Tier Config File with Instance Specific SettingsStarting Service TierCreating DotNetCore Web Server InstanceEnabling Financials User ExperienceCreating http download siteCreating Windows user adminContainer IP Address: 172.26.151.47Container Hostname : c9658bdbe7f0Container Dns Name : c9658bdbe7f0Web Client : https://c9658bdbe7f0/BC/Dev. Server : https://c9658bdbe7f0Dev. ServerInstance : BCFiles:http://c9658bdbe7f0:8080/al-4.0.192371.vsixhttp://c9658bdbe7f0:8080/certificate.cer

以下是最终输出:

Initialization took 116 secondsReady for connections!

请注意,在这种情况下,容器不会在数据库中创建任何用户,因为它假设如果你使用的是现有数据库,那么你也会在该数据库中有现有的用户。同时,请注意,容器将把它自己的加密密钥导入到数据库中,这个密钥用于加密密码。因此,如果你想以这种方式连接多个容器到同一个数据库,你需要确保加密密钥是共享的。

使用 Docker cmdlet 处理正在运行的容器

如果你需要获取 PowerShell 会话进入正在运行的容器,你有两个选项:

  • 首先,你可以使用Enter-PSSession,就像连接到另一台计算机一样,不过你需要给它容器的完整 ID,而不是计算机名。最简单的方式是使用一个子命令查询 Docker 以获取该容器。进入mycontainer容器的 PS 会话将如下所示:
Enter-PSSession -containerid (docker --no-trunc -qf \"name=mycontainer\")

上述语句在以管理员身份运行时有效。

  • 第二个选项是执行容器中的powershell命令,并指示 Docker 为其打开一个交互式终端。对于mycontainer容器,这将如下所示:
docker exec -ti mycontainer powershell

使用这两个命令,你将在容器内启动一个 PowerShell 会话。如果你想运行 Business Central cmdlet,最简单的方式是调用 c:\\run\\prompt.ps1,它会导入所有开发和管理员 cmdlet。

要查看当前正在运行的所有容器,你可以输入并执行 docker ps,它会显示以下输出:

docker psCONTAINER ID IMAGE  COMMAND  CREATED STATUS PORTS NAMES12cec5da3d89 mcr.microsoft.com/businesscentral/sandbox \"powershell -Comma...\" 22 minutes ago Up 21 minutes (healthy) 80/tcp, 443/tcp, 1433/tcp, 7045-7049/tcp, 8080/tcp determined_shockley9518e7e456de mcr.microsoft.com/dynamicsnav:2017-cu22-de \"powershell -Comma...\" 42 minutes ago Up 41 minutes (healthy) 80/tcp, 443/tcp, 1433/tcp, 7045-7049/tcp, 8080/tcp testcont95959a311e54 mcr.microsoft.com/dynamicsnav:2017-cu22-de \"powershell -Comma...\" About an hour ago Up About an hour (healthy) 80/tcp, 443/tcp, 1433/tcp, 7045-7049/tcp, 8080/tcp RKOS-1811113057bf415cc mcr.microsoft.com/dynamicsnav:2017-cu22-de \"powershell -Comma...\" 22 hours ago Up 22 hours (healthy) 80/tcp, 443/tcp, 1433/tcp, 7045-7049/tcp, 8080/tcp VOEKOM0e7970ce5318 mcr.microsoft.com/dynamicsnav:2017-cu22-de \"powershell -Comma...\" 29 hours ago Up 29 hours (healthy) 80/tcp, 443/tcp, 1433/tcp, 7045-7049/tcp, 8080/tcp Buchau6c1c44f170bb mcr.microsoft.com/dynamicsnav:2017-cu22-at \"powershell -Comma...\" 46 hours ago Up 46 hours (healthy) 80/tcp, 443/tcp, 1433/tcp, 7045-7049/tcp, 8080/tcp syAToekom

要查看所有当前存在的容器,你可以使用 docker ps -a,它还包括已退出和/或已停止的容器(输出还会显示一个状态为 Exited 的容器):

docker ps -aCONTAINER ID IMAGE  COMMAND  CREATED STATUS PORTS NAMES12cec5da3d89 mcr.microsoft.com/businesscentral/sandbox \"powershell -Comma...\" 24 minutes ago Exited (1073807364) 9 seconds ago determined_shockley9518e7e456de mcr.microsoft.com/dynamicsnav:2017-cu22-de \"powershell -Comma...\" 43 minutes ago Up 43 minutes (healthy) 80/tcp, 443/tcp, 1433/tcp, 7045-7049/tcp, 8080/tcp testcont95959a311e54 mcr.microsoft.com/dynamicsnav:2017-cu22-de \"powershell -Comma...\" About an hour ago Up About an hour (healthy) 80/tcp, 443/tcp, 1433/tcp, 7045-7049/tcp, 8080/tcp RKOS-18111

停止和启动容器和使用 docker stopdocker start 一样简单。如果你想删除一个容器,你需要先停止(docker stop)然后删除它(docker rm),或者使用 docker rm-f 参数强制删除容器,即使它仍在运行。

请注意,删除容器意味着该容器内的所有文件将丢失,无法恢复。

如果命令执行成功,它只会返回你指定的容器名称或 ID:

docker rm -f 12

请注意,你可以通过容器的名称或 ID 来定位容器。你不需要指定完整的 ID,只需要提供 ID 的前几个字符,以便 Docker 唯一地识别容器。同时,注意 docker ps 会为每个容器显示一个截断的 ID,你可以使用 docker ps --no-trunc 来获取完整的 ID。

使用 navcontainerhelper 创建本地可用的环境

为了让用户更容易采用和使用 Dynamics 365 Business Central Docker 镜像,微软创建了一个名为 navcontainerhelper 的 PowerShell 模块。它使用与纯 Docker 命令相同的镜像和命令,且在许多地方,你可以看到 cmdlet 是如何转化为 Docker 命令的。它还包含了一些非常有价值的 PowerShell 脚本集合,帮助完成 Dynamics 365 Business Central 中常见的开发、构建、测试和发布任务。

安装 navcontainerhelper 并保持其更新

要使用 navcontainerhelper 模块,你需要从 PowerShell Gallery 安装它,如下所示:

install-module navcontainerhelper -force

如果有新版本的 navcontainerhelper(在写这篇文档时,至少每隔几周就会有一次更新),并且包含新的有用功能和 bug 修复,只需运行以下命令:

update-module navcontainerhelper -force

你的第一个容器

为了跟随上一节的相同示例,你将学习如何使用 navcontainerhelper 运行你的第一个容器。不过,navcontainerhelper 需要你给它一个名称,并做出关于身份验证的明确选择。如果你没有提供任何其他参数,它会假设你想使用 Windows 身份验证,并要求输入密码,以便它可以在容器内创建一个具有相同用户名和密码的用户。这也启用了 单点登录 (SSO) 功能。考虑以下命令:

New-NavContainer -accept_eula -imageName mcr.microsoft.com/businesscentral/sandbox mycontainerNavContainerHelper is version 0.6.4.16NavContainerHelper is running as administratorHost is Microsoft Windows Server 2019 Datacenter - ltsc2019Docker Client Version is 19.03.2Docker Server Version is 19.03.2Pulling image mcr.microsoft.com/businesscentral/sandbox:latest-ltsc2019latest-ltsc2019: Pulling from businesscentral/sandbox3889bb8d808b: Already existse0718b11f512: Pulling fs layer…76a160cd3c52: Pull completeDigest: sha256:3eb2e9d87102c135c1b0c004523abbbe7bff53fc98fe5527a4e85e9ff198d1fdStatus: Downloaded newer image for mcr.microsoft.com/businesscentral/sandbox:latest-ltsc2019Using image mcr.microsoft.com/businesscentral/sandbox:latest-ltsc2019Creating Container mycontainerVersion: 15.0.36626.37711-w1Style: sandboxPlatform: 15.0.37582.0Generic Tag: 0.0.9.95Container OS Version: 10.0.17763.737 (ltsc2019)Host OS Version: 10.0.17763.678 (ltsc2019)Using locale en-USUsing process isolationDisabling the standard eventlog dump to container log every 2 seconds (use -dumpEventLog to enable)Files in C:\\ProgramData\\NavContainerHelper\\Extensions\\mycontainer\\my:- AdditionalOutput.ps1- MainLoop.ps1Creating container mycontainer from image mcr.microsoft.com/businesscentral/sandbox:latest-ltsc2019db420a5aec3da0b94b2a466432c160f3a28bd7da5ed83d5ea683ee5e7bd330ffWaiting for container mycontainer to be readyInitializing...Starting ContainerHostname is mycontainerPublicDnsName is mycontainerUsing Windows AuthenticationStarting Local SQL ServerStarting Internet Information ServerModifying Service Tier Config File with Instance Specific SettingsStarting Service TierRegistering event sourcesCreating DotNetCore Web Server InstanceEnabling Financials User ExperienceCreating http download siteCreating Windows user tobias.fensterSetting SA Password and enabling SACreating SUPER userContainer IP Address: 172.23.237.104Container Hostname : mycontainerContainer Dns Name : mycontainerWeb Client : http://mycontainer/BC/Dev. Server : http://mycontainerDev. ServerInstance : BC Files:http://mycontainer:8080/al-4.0.192371.vsixInitialization took 311 secondsReady for connections!Reading CustomSettings.config from mycontainerCreating Desktop Shortcuts for mycontainerContainer mycontainer successfully created

正如你从最后几行看到的,navcontainerhelper甚至会创建方便的桌面快捷方式。它们允许你通过简单的双击访问Web Client,或在容器内打开 PowerShell 或命令提示符。这些快捷方式实际上使用了你在前几节中看到的相同的docker exec命令。

New-NavContainer有一个很长的参数列表,这些参数要么仅仅是环境参数的映射,要么是非常有用的小功能。举个例子,如果你指定了-updateHosts,那么navcontainerhelper会将容器的名称和 IP 地址添加到你笔记本电脑上的 hosts 文件中。这意味着你不需要使用 IP 地址——你可以使用容器名称作为地址!当然,也有其他方法可以做到这一点,但没有像在启动命令中指定一个简单的参数那么方便。

拉取新镜像版本

拉取新镜像在navcontainerhelper中的工作方式与普通 Docker 完全相同;没有特别的命令。然而,你可以为New-NavContainer命令指定-alwaysPull参数,正如名称所示——每次运行容器之前,都会尝试拉取新的镜像版本。

navcontainerhelper实际上会自动添加更多方便的优化。如果你没有在标签中指定ltsc2016ltsc2019,它会自动确定最佳的容器平台并使用它。它还会自动判断是否可以使用进程隔离,并在必要时将内存限制设置为 4GB。

使用更多环境参数、卷和端口映射

如前所述,New-NavContainer提供了许多仅设置环境参数的选项。在我们之前使用docker run的示例中,执行了以下操作:

docker run -e accept_eula=y -e usessl=n -v \"c:\\dev\\addins:c:\\program files\\microsoft\\Dynamics NAV\\150\\Service Tier\\Add-ins\\mine\" -p 80:80 –name mycontainer mcr.microsoft.com/businesscentral/sandbox

要在navcontainerhelper中实现相同的功能,我们会使用以下命令:

New-NavContainer -accept_eula -PublishPorts 80 -additionalParameters @(\'--volume c:\\dev\\addins:c:\\program files\\microsoft\\Dynamics NAV\\150\\Service Tier\\Add-ins\\mine\') -containerName mycontainer -imageName mcr.microsoft.com/businesscentral/sandbox

让我们来比较一下这些功能:

  • 接受 EULA(最终用户许可协议)是通过-accept_eula完成的,且不使用 SSL 是navcontainerhelper的默认设置。

  • 本地文件夹与容器中Add-ins文件夹的映射是通过-additionalParameters参数来实现的。这是navcontainerhelper中用于指定任何你可能需要的docker run参数的机制,这些参数尚未被涵盖。

  • 端口映射是通过-PublishPorts参数来实现的。

  • 命名容器是通过-containerName参数来完成的。

再次强调,navcontainerhelper会自动添加更多内容:c:\\programdata\\navcontainerhelper始终会与容器共享,并作为容器内的同一文件夹。此外,每个容器都有自己在c:\\programdata\\navcontainerhelper\\extensions\\中的文件夹,所有本地与该容器相关的内容都会放在这里。

连接到现有的 SQL Server

navcontainerhelper使得这个任务比直接使用 Docker 稍微方便一些。你需要指定相同的参数,但你可以提供一个凭证对象,而不是将用户名和密码明文写入。提醒一下,下面是docker run命令的样子:

docker run -e accept_eula=y -e databaseServer=sqlserver -e databaseUsername=sqluser -e \"databasePassword=1SuperSecretPwd!\" -e databasename=FinancialsW1 mcr.microsoft.com/businesscentral/sandbox

以下是使用navcontainerhelper的相同命令。它将打开一个凭证输入对话框,在那里你可以输入 SQL 用户名和密码。但与直接将密码明文写入环境变量不同,navcontainerhelper确保密码得到安全处理,如下所示:

New-NavContainer -accept_eula -databaseServer sqlserver -databaseCredential (Get-Credential) -databaseName FinancialsW1 -imageName mcr.microsoft.com/businesscentral/sandbox:latest -containerName mycontainer -auth NavUserPasswordcmdlet Get-Credential at command pipeline position 1Supply values for the following parameters:CredentialNavContainerHelper is version 0.6.4.16NavContainerHelper is running as administratorHost is Microsoft Windows Server 2019 Datacenter - ltsc2019Docker Client Version is 19.03.2Docker Server Version is 19.03.2Pulling image mcr.microsoft.com/businesscentral/sandbox:latest-ltsc2019latest-ltsc2019: Pulling from businesscentral/sandbox3889bb8d808b: Already existse0718b11f512: Pulling fs layer…76a160cd3c52: Pull completeDigest: sha256:3eb2e9d87102c135c1b0c004523abbbe7bff53fc98fe5527a4e85e9ff198d1fdStatus: Downloaded newer image for mcr.microsoft.com/businesscentral/sandbox:latest-ltsc2019Using image mcr.microsoft.com/businesscentral/sandbox:latest-ltsc2019Creating Container mycontainerVersion: 15.0.36626.37711-w1Style: sandboxPlatform: 15.0.37582.0Generic Tag: 0.0.9.95Container OS Version: 10.0.17763.737 (ltsc2019)Host OS Version: 10.0.17763.678 (ltsc2019)Using locale en-USUsing process isolationDisabling the standard eventlog dump to container log every 2 seconds (use -dumpEventLog to enable)Files in C:\\ProgramData\\NavContainerHelper\\Extensions\\mycontainer\\my:- AdditionalOutput.ps1- MainLoop.ps1Creating container mycontainer from image mcr.microsoft.com/businesscentral/sandbox:latest-ltsc2019db420a5aec3da0b94b2a466432c160f3a28bd7da5ed83d5ea683ee5e7bd330ffWaiting for container mycontainer to be readyInitializing...Starting ContainerHostname is mycontainerPublicDnsName is mycontainerUsing NavUserPassword AuthenticationStarting Internet Information ServerImport Encryption KeyCreating Self Signed CertificateSelf Signed Certificate Thumbprint 583BDDBAB357DB4B4AB722284629195E27328B7EModifying Service Tier Config File with Instance Specific SettingsStarting Service TierCreating DotNetCore Web Server InstanceEnabling Financials User ExperienceCreating http download siteCreating Windows user adminSetting SA Password and enabling SACreating SUPER userContainer IP Address: 172.23.237.104Container Hostname : mycontainerContainer Dns Name : mycontainerWeb Client : http://mycontainer/BC/Dev. Server : http://mycontainerDev. ServerInstance : BCFiles:http://mycontainer:8080/al-4.0.192371.vsixInitialization took 99 secondsReady for connections!Reading CustomSettings.config from mycontainerCreating Desktop Shortcuts for mycontainerContainer mycontainer successfully created

请注意,使用docker run时默认的身份验证机制是NavUserPassword,而navcontainerhelper的默认身份验证机制是 Windows,因此为了实现相同的效果,我们也需要指定这一点。

使用 NavContainerHelper 管理你的运行中的容器

navcontainerhelper中没有专门的命令让你查看正在运行的容器,因此你只需要使用前面章节中介绍的相同docker ps命令。也有启动和停止容器的命令(分别是Start-NavContainerStop-NavContainer),但它们只是docker startdocker stop的简单封装,没有额外的好处。

移除容器的操作是通过Remove-NavContainer完成的,它做的事情稍微多一些:它会清理快捷方式和特定于容器的文件夹,如果你指定了-updatehosts,它还会移除 hosts 文件中的相关条目。

还有一个命令可以让你进入容器会话,叫做Enter-NavContainer。这会给你一个 PowerShell 会话,进入容器内部,另外还可以调用c:\\run\\prompt.ps1,这会立刻提供所有开发和管理的 cmdlet,并且给你一个格式良好的提示,让你始终知道自己在哪里。考虑以下命令:

Enter-NavContainer mycontainer[MYCONTAINER]: PS C:\\Run> Get-NAVServerInstanceServerInstance : MicrosoftDynamicsNavServer$BCDisplayName : Dynamics 365 Business Central Server [BC]State : RunningServiceAccount : NT AUTHORITY\\SYSTEMVersion : 15.0.37582.0Default : True

本地环境的集中式可用性

到目前为止,我们只涵盖了本地运行的容器,但根据你的情况,你可能希望设置一个或多个中央虚拟机,这些虚拟机由运维团队而非开发人员或顾问来管理。在这种情况下,之前解释过的相同选项仍然适用,但你需要考虑一些额外的主题。你还需要决定是否希望提供一个完全自助服务的环境,允许开发人员或顾问自行配置新的沙盒,或者希望运维团队来处理创建和删除沙盒的工作。

如果你的运维团队负责这些操作,那么你唯一需要关注的就是网络配置。你有以下两种选择,可以使你的容器端口在 Docker 主机外部可用:

  • 端口映射让你可以将容器端口映射到主机端口。然而,随着时间的推移,这会变得繁琐,因为你需要为每个容器找到可用的端口,并告诉你的用户应该使用哪些端口。

  • 透明网络使容器能够获得自己的 IP 地址(静态或 DHCP)并保持标准端口。此方法的维护工作量要少得多。我们现在将更详细地讨论这个问题。

所以,创建透明网络非常简单。在最简单的情况下,你只需要编写以下命令来创建一个名为 transpNet 的透明网络:

docker network create -d transparent transpNet

你也可以设置子网或 IP 范围,但这超出了本书的范围。请查看 Docker 的在线文档或运行 docker network create --help 以了解更多信息。告诉容器使用透明网络也很容易,因为有一个名为 --network 的参数。在运行纯 Docker 时,使用如下命令:

docker run -e accept_eula=y --network transpNet mcr.microsoft.com/businesscentral/sandbox

navcontainerhelper 在写作时 New-NavContainer 没有特定的网络参数,但你可以使用 -additionalParametersparameter 来代替:

New-NavContainer -accept_eula -additionalParameters @(\'--network transpNet\') -containerName mycontainer -imageName mcr.microsoft.com/businesscentral/sandbox

这样,容器将获得自己的 IP 地址,并且你可能也能通过名称从 Docker 主机外部访问它。请注意,这很大程度上取决于主机所处网络的设置。它类似于将一个新虚拟机添加到网络中,依赖于网络管理员设置的安全机制,这可能在没有进一步设置的情况下无法正常工作。

如果你想要为开发人员或顾问提供一个可以创建自己环境的环境,你需要解决两个问题:

  • 你希望如何处理容器操作(创建、启动、停止和删除操作)? 你可以允许用户通过 RDP 或 PowerShell 访问主机,但这会使权限管理变得复杂。你还可以使用如 Portainer(portainer.io)这样的工具,这是一个处理容器的 GUI。在这里,用户可以管理他们的容器,并且你可以例如创建具有预定义值的容器参数模板。然而,请注意,在这种情况下,你将无法使用 navcontainerhelper,因为这意味着需要在主机上运行 PowerShell 脚本。另一种选择是你自己创建某种前端应用程序,但这当然需要一些时间。

  • 用户如何访问容器中的文件系统? 这取决于你对 Dynamics 365 Business Central 的使用。通常需要访问文件系统。如果你已经运行了全云解决方案,这无论如何都不可行,但如果你仍有本地客户,这可能是一个问题。最简单的解决方案是始终将一个卷映射到你的容器中,例如 c:\\shared,并允许用户访问主机上的文件夹。

托管在 Azure 虚拟机上的容器

如果你想在 Azure 虚拟机中运行沙盒,你面临的挑战几乎与在本地虚拟机中使用集中式沙盒相同。不过,你可以走捷径:微软提供了预安装了 Docker 的标准虚拟机镜像,比如带有容器的 Windows Server 2019 Datacenter,这样你就不必担心这一点了。

如果你想使用 navcontainerhelper,你需要先安装它,然后你就可以开始使用了。一个更快捷的方法是使用微软提供的快速启动模板之一,例如aka.ms/getbc。这将创建一个 Azure 虚拟机,安装 Docker 和 navcontainerhelper,拉取最新的 Dynamics 365 Business Central 镜像(默认为本地版镜像),并为你启动它。除此之外,你还会得到一个漂亮的日志,显示所有正在进行的“魔法”进展。之后,你可以使用该虚拟机根据需要创建更多沙盒。

然而,在 Azure 虚拟机中有一个问题,使得处理它们变得更加复杂:你无法使用透明网络。这是有多个原因的,而且很可能在近期不会改变,所以你必须考虑其他解决方案。一种解决方案是端口映射,正如我们之前提到的,但这也需要相当多的维护。最简单的方法是使用反向代理,例如 nginx 或 Traefik,但这也超出了本书的范围。

你可以在www.axians-infoma.de/techblog/running-multiple-nav-bc-containers-on-an-azure-vm/找到快速入门介绍。

选择正确的镜像

现在你已经知道如何创建和运行沙盒,唯一的问题是你想使用哪个版本;做出这个决定可能相当复杂。关于如何做出有效决定的基本知识将在本节中总结。

官方的公开发布版本始终可以在注册表(mcr.microsoft.com)中找到,以下是相关的仓库和镜像名称:

  • mcr.microsoft.com/businesscentral/sandbox:Dynamics 365 Business Central SaaS 版本的沙盒镜像

  • mcr.microsoft.com/businesscentral/onprem:Dynamics 365 Business Central 本地版

  • mcr.microsoft.com/dynamicsnav:旧版 Dynamics NAV 产品,从 Dynamics NAV 2016 开始

未发布版本的预览版可以在 bcinsider.azurecr.io 注册表中找到,以下是相关的仓库和镜像名称:

  • bcinsider.azurecr.io/bcsandbox:Dynamics 365 Business Central SaaS 版本下一个次要版本的预览版

  • bcinsider.azurecr.io/bconprem:Dynamics 365 Business Central 本地版下一个次要版本的预览版

  • bcinsider.azurecr.io/bcsandbox-master:Dynamics 365 Business Central SaaS 版本下一个重大版本的预览版

  • bcinsider.azurecr.io/bconprem-master:下一次主要发布的 Dynamics 365 Business Central 本地版预览

请注意,再次提醒,你需要bcinsider.azurecr.io的登录凭据,可以通过在微软的协作平台上注册“Ready to Go!”程序后获取。

当你决定使用哪张镜像时,还需要决定使用哪个标签,代表微软的某个特定版本。所有镜像都允许你指定语言(gbdedk等)和基础操作系统(Windows Server 2016 的ltsc2016和 Windows Server 2019 的ltsc2019)。发布的本地版本也允许你使用与传统安装相同的命名约定,通过参考它们的累积更新名称来使用。

考虑以下示例,以便了解语法:

  • Dynamics 365 Business Central 2018 秋季版(1810),CU 11,德语版,基于 Windows Server 2016:
mcr.microsoft.com/businesscentral/onprem:1810-cu11-de-ltsc2016
  • Dynamics 365 Business Central 2019 春季版(1904),CU 5,丹麦版,基于 Windows Server 2019:
mcr.microsoft.com/businesscentral/onprem:1904-cu5-dk-ltsc2019
  • Dynamics 365 Business Central 2019 秋季版(1910),CU 1,澳大利亚版,基于 Windows Server 2019:
mcr.microsoft.com/businesscentral/onprem:1910-cu1-au-ltsc2019
  • Dynamics NAV 2017,CU 28,英国版,基于 Windows Server 2019:
mcr.microsoft.com/businesscentral/dynamicsnav:2017-cu28-gb-ltsc2019

已发布的 SaaS 版本允许你指定更新版本,而不是累积更新:

  • Dynamics 365 Business Central SaaS 更新 25,西班牙版,基于 Windows Server 2016:
mcr.microsoft.com/businesscentral/sandbox:update25-es-ltsc2016

预览版只允许你指定语言和 Windows Server 版本:

  • 下一次小版本的 SaaS 版 Dynamics 365 Business Central 的最新预览,德语版,基于 Windows Server 2019:bcinsider.azurecr.io/bcsandbox:de-ltsc2019

  • 下一次主要发布的 Dynamics 365 Business Central 本地版预览,丹麦版,基于 Windows Server 2016:bcinsider.azurecr.io/bconprem-master:dk-ltsc2016

如果你没有指定所有内容,会有默认值,因此mcr.microsoft.com/businesscentral/onprem将给你最新的累积更新版本,基于 Windows Server 2016 的最新 Dynamics 365 Business Central 本地版本 W1 版。为了避免意外情况,通常最好尽可能详细地指定标签。

修改标准镜像中的脚本

如你所见,Dynamics 365 Business Central 的容器镜像有很多配置选项,允许你改变许多行为。然而,如果你遇到需要运行不同容器配置的情况,镜像还有一个王牌:你可以覆盖容器中的任何脚本。

这个机制通过将一个与想要覆盖的脚本同名的脚本放入容器中的 c:\\run\\my 文件夹来工作。最简单的方法是通过卷来实现。假设你有一个文件夹,比如 c:\\bc-override,其中有一个 AdditionalSetup.ps1 文件,你可以这样做:

docker run -e accept_eula=y -v c:\\bc-override:c:\\run\\my mcr.microsoft.com/businesscentral/onprem

当容器执行到调用 AdditionalSetup.ps1 的位置时,它会检查在 c:\\run\\my 中是否存在该文件,如果存在,则调用它。如果不存在,它会调用标准脚本,该脚本存储在 c:\\run 中。这个脚本可能如下所示:

Write-Host \"----- Hello from the override script --------------------\"

如果是这样,当你启动容器时,你将看到以下输出:

Initializing...Starting ContainerHostname is 4e58d9587fb0PublicDnsName is 4e58d9587fb0Using NavUserPassword AuthenticationStarting Local SQL ServerStarting Internet Information ServerCreating Self Signed CertificateSelf Signed Certificate Thumbprint 1462D57EE355D19018232160C396159313A20893Modifying Service Tier Config File with Instance Specific SettingsStarting Service TierCreating DotNetCore Web Server InstanceEnabling Financials User ExperienceCreating http download siteCreating Windows user adminSetting SA Password and enabling SACreating admin as SQL User and add to sysadminCreating SUPER user----- Hello from the override script --------------------Container IP Address: 172.26.148.48Container Hostname : 4e58d9587fb0Container Dns Name : 4e58d9587fb0Web Client : https://4e58d9587fb0/BC/Admin Username : adminAdmin Password : Rohy1060Dev. Server : https://4e58d9587fb0Dev. ServerInstance : BCFiles:http://4e58d9587fb0:8080/al-4.0.192371.vsixhttp://4e58d9587fb0:8080/certificate.cerInitialization took 117 secondsReady for connections!

使用 navcontainerhelper 工具,你可以像这样调用它:

New-NavContainer -accept_eula -imageName mcr.microsoft.com/businesscentral/sandbox -myScripts @(\"c:\\bc-override\\AdditionalSetup.ps1\") mycontainer

或者,由于 navcontainerhelper 提供了一种更方便的方法,你可以直接将你的 PowerShell 脚本代码内联添加:

New-NavContainer -accept_eula -imageName mcr.microsoft.com/businesscentral/sandbox -myscripts @( @{ \"AdditionalSetup.ps1\" = \"Write-Host ‘----- Hello from the override script --------------------\'\" } ) mycontainer

借助这个强大的功能,你可以更改容器中的每个脚本以适应你的需求。为了了解可以调整的内容,请查看 github.com/Microsoft/nav-docker/tree/master/generic/Run

创建你自己的镜像

通过我们刚才看到的机制,我们可以更改容器中的所有内容。但是,如果你想确保你的同事、合作伙伴或客户获得完全相同的修改,而不必得到 my-scripts 覆盖正确?或者,如果你需要将某些 DLL 或其他文件放入容器中,并希望将它们作为你自己的镜像的一部分交付呢?答案是构建你自己的镜像,幸运的是,这也非常简单。

Docker 有一个分层概念,使得镜像变成了一个层的堆叠。你需要做的就是将自己的层放在标准镜像之上。你可以通过使用 Dockerfile 来实现这一点,Dockerfile 需要引用你想要扩展的标准镜像,然后再执行你想要的操作。假设你想将存储在 c:\\bc\\dlls 中的某些 DLL 文件放入镜像的 Add-ins 文件夹,并将你自己位于 c:\\bc\\override 文件夹中的 AdditionalSetup.ps1 脚本放入镜像的 c:\\run 文件夹中。你的 Dockerfile 将如下所示,存储在 c:\\bc 文件夹中:

FROM mcr.microsoft.com/businesscentral/sandboxCOPY [\"./dlls/*\", \"c:/Program Files/Microsoft Dynamics NAV/150/Service/Add-ins/\"]COPY ./override/AdditionalSetup.ps1 c:/run/

要构建这个镜像,你需要在 c:\\bc 中运行 docker build 命令,并使用 -t 参数为你的镜像命名:

docker build -t myimage

结果将类似于以下内容:

Sending build context to Docker daemon 7.168kBStep 1/3 : FROM mcr.microsoft.com/businesscentral/sandbox ---> 20f72db6c9a9Step 2/3 : COPY ./dlls/* c:/Program Files/Microsoft Dynamics NAV/150/Service/Add-ins/---> f202642914a9Step 3/3 : COPY ./override/AdditionalSetup.ps1 c:/run/ ---> 1164c1273517Removing intermediate container e9070e72cbaaSuccessfully built 1164c1273517Successfully tagged myimage:latest

配置完成后,你可以像使用其他镜像一样使用你的镜像:

docker run -e accept_eula=y myimage

与他人共享此镜像的方式是通过 Docker 仓库。对于基于官方 Microsoft 镜像构建的镜像,这将通过私有仓库来完成。如何设置私有仓库超出了本书的范围,但如果你想了解更多,可以参考 docs.docker.com/registry/ 作为一个好的起点。

总结

在本章中,我们了解了在线和基于 Docker 的沙盒的基础知识,以及如何最优化地使用它们。我们强调了掌握 Docker 的基础知识及如何从在线仓库中的 Dynamics 365 Business Central 镜像创建基本容器的必要性。

借助本章中获得的技能,你应该能够创建自己的容器,选择合适的镜像,并在处理自定义沙盒环境时熟悉navcontainerhelper工具。

你还应该能够掌握 Dockerfile 的格式,并通过覆盖脚本和创建自己的 Dynamics 365 Business Central 沙盒基线,对标准镜像进行深入修改。

在下一章中,我们将通过学习 AL 语言的基础知识,开始我们的开发之旅。

第二部分:为 Dynamics 365 Business Central 开发扩展

在本节中,我们将为您提供一个关于如何使用新的扩展模型为 Dynamics 365 Business Central 开发定制化解决方案的完整概述。

本节包括以下章节:

  • 第四章,扩展开发基础

  • 第五章,为 Dynamics 365 Business Central 开发定制化解决方案

  • 第六章,高级 AL 开发

  • 第七章,使用 AL 开发报表

第四章:扩展开发基础

在上一章中,我们概述了新的现代开发环境,并且学习了如何使用 AL 语言扩展和现代开发环境启动一个新的 Dynamics 365 Business Central 扩展项目。

在本章中,我们将详细探讨新扩展开发模型中的对象,并讲解如何使用 AL 创建新对象、扩展标准对象,以及如何处理 AL 扩展项目。更具体地说,我们将涵盖以下主题:

  • 扩展开发基础

  • AL 对象的概述

  • 如何在扩展项目中创建基本对象

  • 处理 AL 项目的最佳实践

  • AL 对象指南

在本章结束时,你将了解不同的 AL 对象类型,如何创建和使用它们,并且(更广泛地说)你将准备好开始一个 Dynamics 365 Business Central 扩展项目,使用 AL 语言扩展和现代开发环境(Visual Studio Code)。

技术要求

为了跟随本章内容并实验 AL 语言中的基本对象创建,你将需要以下内容:

  • Microsoft Dynamics 365 Business Central 沙箱环境(本地安装在 Docker 容器中或在线环境)

  • Visual Studio Code

  • AL 语言扩展,可以从 Visual Studio Code 市场安装

关于扩展的基本概念

正如你已经知道的,在 Microsoft Dynamics 365 Business Central SaaS 中,你无法访问数据库或标准的基础代码(这在本地版本中有所不同,在本地版本中你仍然可以访问基础代码,并且修改该核心是你的责任)。在 SaaS 世界中,你无法更改数据库架构,也不能修改标准的业务逻辑。

在以前版本的 Microsoft Dynamics ERP 中,我们一直在讨论代码修改。在 SaaS 世界中,我们必须开始思考一个新概念:代码扩展。要自定义 Dynamics 365 Business Central,你必须创建扩展

扩展(根据微软的指南)被定义为一种可安装的功能,其构建方式不会直接改变源资源,并且以预配置包的形式分发

扩展通过使用事件与标准基础代码进行交互。以下图示展示了在 Dynamics 365 Business Central 扩展中的不同层次之间如何进行事件交互:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/ms-ms-dyna365/img/0b0b9898-b8e8-4931-8fcb-3286f7eeed49.png

事件本质上是一个由代码触发的函数,当业务流程中发生某些事情时该函数会被调用。这个函数通常定义为事件发布者函数。它仅包含一个签名,并不会执行任何代码。包含事件发布者函数的对象被定义为发布者

在 Dynamics 365 Business Central 中,事件根据以下类型进行分类:

  • 数据库事件:这些是在对表对象进行数据库操作(如插入、修改、删除和重命名)时由系统自动触发的事件。

  • 页面事件:这些是在页面对象中执行操作时由系统自动触发的事件。

  • 业务事件:这些是由 C/AL 代码触发的自定义事件。业务事件定义了一个正式契约,并隐含承诺在未来的应用程序版本中不进行更改。

  • 集成事件:这些是由 C/AL 代码触发的自定义事件。它们与业务事件类似,但在应用程序的未来版本中,它们的签名可能会发生变化。

  • 全局事件:这些是由应用程序触发的系统事件。

当事件被发布并由代码触发时,它将可供应用程序订阅。订阅者是一个代码功能,它监听并处理已发布的事件。它订阅一个特定的事件发布器功能,并通过向其中添加自定义业务逻辑来处理该事件。当应用程序触发事件时,订阅者功能会自动被调用,并执行其代码。

请记住,你可以有多个订阅者订阅同一个事件发布器功能。在这种情况下,订阅者执行的顺序是无法确定的(是随机的),因此在设计代码时要小心事件链的顺序。

事件确保你可以与标准业务流程交互或修改其行为,而无需更改基础代码。

Dynamics 365 Business Central 在其标准代码中暴露了大量事件,并且每月都会添加新的事件。你可以通过以下链接请求新的事件:github.com/Microsoft/ALAppExtensions/issues。要获得 Dynamics 365 Business Central 中已发布事件的完整概览,建议你查看以下 GitHub 仓库:github.com/waldo1001/blog.CALAnalysis/tree/master/Published%20Events

在本节中,我们学习了事件是每个 AL 扩展的基本构建块。在下一节中,我们将概述可用的 AL 对象,并学习如何使用 AL 语言扩展创建它们。

理解 AL 语言的基础

Dynamics 365 Business Central 的扩展是使用AL 语言编写的。使用 AL 语言,你可以创建新对象、扩展标准对象,并为你的应用程序创建自定义业务逻辑。

你通过使用 Visual Studio Code 作为开发环境,并使用 AL 语言扩展(如我们在第二章中描述的,掌握现代开发环境)来为 Dynamics 365 Business Central 创建扩展。安装后,你将获得完整的 AL 项目开发支持。

所有 Dynamics 365 Business Central 功能都作为对象进行编码(新对象或标准对象的扩展),这些对象在.al文件中定义。一个.al文件可以定义多个对象(尽管我们不推荐这样做)。

扩展程序随后被编译为.app包文件,这个文件就是你在最终环境中发布的扩展。

截至目前,AL 语言扩展对于 Visual Studio Code 提供了以下对象:

  • 表对象

  • 表扩展对象

  • 页面对象

  • 页面扩展对象

  • 代码单元对象

  • 报表对象

  • 枚举对象

  • XMLport 对象

  • 查询对象

  • 控件附加组件(JavaScript)

  • 配置文件和页面自定义

我们将在接下来的章节中详细查看主要对象。其中一些对象(如报告、页面自定义和附加组件)将在后续章节中介绍。

AL 语言扩展包含了许多用于定义对象和处理语言任务的代码片段。主要的标准代码片段如下:

  • 对象

    • tpagecust: 标准页面的新自定义

    • tpageext: 标准页面的新扩展

    • ttableext: 标准表的新扩展

    • tquery: 新查询

    • treport: 新报告

    • txmlport: 新的 xmlport

    • tpage: 在这里,我们可以选择是获取一个新的列表还是一个新的卡片

    • tcodeunit: 新代码单元

  • 代码

    • tcaseelse: 带有 else 的 Case 语句

    • tcaseof: 没有 else 的 Case 语句

    • tfor: For 语句

    • tforeach: Foreach 语句

    • tif: 带有 begin 和 end 的 If 语句

    • tifelse: 带有 begin 和 end else 的 If 语句

    • tisempty: 带有 begin 和 end 的 Isempty 语句

    • tisemptyelse: 带有 begin end else 的 Isempty 语句

    • trepeat: 带有 begin 和 end 子句的重复循环

    • twhile: While 语句

    • twith: With 语句

  • 配置文件

    • tprofile: 允许我们创建一个带有页面自定义的新的配置文件
  • 事件

    • teventbus: 允许我们创建一个业务事件

    • teventint: 允许我们创建一个集成事件

    • teventsub: 允许我们创建一个订阅者事件

  • 字段和键

    • tfield: 新字段,无类型(我们需要手动填写一个类型)。

    • tfieldbiginteger: 大整数类型。

    • tfieldboolean: 布尔字段。

    • tfieldblob: Blob 字段。

    • tfieldcode: 代码字段。你只需要设置字段的长度。

    • tfielddate: 日期字段。

    • tfielddateformula: 日期公式字段。

    • tfielddatetime: 日期时间字段。

    • tfielddecimal: 十进制字段。

    • tfieldduration: 持续时间字段。

    • tfieldguid: GUID 字段。

    • tfieldoption: 选项字段。在这种情况下,OptionMember属性会自动添加。

    • tfieldrecorid: RecordID 字段。

    • tfieldtext:文本字段。你只需要输入字段的长度。

    • tfieldtime:时间字段。

    • tkey:向表中添加一个新键。

  • 页面上的字段和操作

    • tfieldpage:向页面添加一个字段。

    • taction:向页面添加一个操作。

  • 触发器

    • ttrigger:创建触发器定义。

    • tprocedure:创建过程定义。

在 Visual Studio Code 中安装 AL 语言扩展后,你可以通过转到“视图” | “命令面板”并选择 AL:Go!来启动一个新的 AL 项目。

Visual Studio Code 会要求你提供一个文件夹,以便它可以在其中创建项目,然后要求你选择目标平台(Dynamics 365 Business Central 版本)。选择 4.0 Business Central 2019 版本第二波发布:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/ms-ms-dyna365/img/76a129b4-ea58-4eee-9b66-f6a1088115fe.png

现在,Visual Studio Code 将为你配置项目。它会创建launch.json文件,以便你可以连接到开发环境,以及带有扩展清单文件的app.json文件(如第二章,掌握现代开发环境所述)。

现在,你可以开始定义组成你解决方案的对象。

表定义

使用 AL 扩展,你没有图形化工具来设计表(就像我们以前在 CSIDE 中做的那样);相反,你需要使用代码来创建表。

可以通过使用ttable代码段创建一个表定义:

table id MyTable{ DataClassification = ToBeClassified; fields { field(1;MyField; Integer) { DataClassification = ToBeClassified;  } } keys { key(PK; MyField) { Clustered = true; } } var myInt: Integer; trigger OnInsert() begin end; trigger OnModify() begin end; trigger OnDelete() begin end; trigger OnRename() begin end;}

要定义一个表,你需要指定一个ID(必须在应用程序中唯一)和一个名称(也必须是唯一的)。然后,你可以设置表的属性(使用Ctrl + 空格键来发现所有可用属性):

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/ms-ms-dyna365/img/bffce792-71fd-4ffb-ba92-663c196b944a.png

一个表对象具有以下主要属性:

  • Caption:标识表在用户界面中显示的字符串。

  • DataCaptionFields:设置在显示此表内容的页面中,位于标题左侧的字段。

  • DataPerCompany:设置一个值,指示表数据是适用于数据库中的所有公司,还是仅适用于当前公司(当默认值为true时,数据仅适用于当前公司)。

  • DrillDownPageID:设置用作下钻的页面 ID。

  • LookupPageID:设置用作查找的页面 ID。

  • LinkedObject:仅适用于本地部署;它指定一个指向 SQL Server 对象的链接。

  • Permissions:设置对象是否具有执行某些操作所需的额外权限,这些操作适用于一个或多个表。

  • TableType:指定表的类型(普通、CRM、ExternalSQL、Exchange 或 MicrosoftGraph)。

  • ExternalName:当你在TableType属性中指定 CRM 或 ExternalSQL 时,此属性出现,并指定外部数据库中原始表的名称。

  • ExternalSchema:当你在TableType属性中指定 CRM 或 ExternalSQL 时,此属性出现,并指定外部数据库中数据库架构的名称。

  • ReplicateData: 指定表是否必须复制到云服务(默认值为 true)。

  • Extensible: 设置对象是否可以扩展。

表对象包含一组字段。表的字段可以通过使用 tfield 代码段创建:

field(id; MyField; Blob){ DataClassification = ToBeClassified; FieldPropertyName = FieldPropertyValue;}

字段由 ID(必须在声明表及其所有扩展中唯一)、名称(也必须在声明表及其所有扩展中唯一)和 类型(字段的数据类型)定义。

建议始终设置 Caption 属性(对于表和字段),并将 DataClassification 属性(用于定义 GDPR 法规的数据敏感性)设置为除 ToBeClassified 以外的值。字段可以具有其特定的属性,您可以根据需要进行设置(如以下屏幕截图所示的可选属性):

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/ms-ms-dyna365/img/b8264379-9c65-4a61-8fab-e37b94c9e958.png

表还包含一组 。您可以使用 tkey 代码段定义键:

key(MyKey; MyField){}

表的键由 名称 和组成键的 字段(以逗号分隔的表字段列表)定义。如果表的主键是该键,则键可以将 Clustered 属性设置为 true。聚集索引是一种特殊类型的索引,它重新排序表中记录的物理存储方式,因此一个表只能有一个聚集索引。

表还可以具有触发器(OnInsertOnModifyOnDeleteOnRename),在表内部,您可以定义自己的方法。

页面对象定义

页面对象是您在 Dynamics 365 Business Central 中为用户提供的用户界面。您可以使用 tpage 代码段在 AL 中定义页面对象:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/ms-ms-dyna365/img/5a02afc5-14a3-43c0-9220-6a04d9880558.png

前三个选项允许您创建以下页面类型:

  • Card 页面

  • API 页面

  • List 页面

Card 页面(第一个选项)定义如下:

page Id MyPage{ PageType = Card; ApplicationArea = All; UsageCategory = Administration; SourceTable = TableName; layout { area(Content) { group(GroupName) { field(Name; NameSource) {  ApplicationArea = All; } } } } actions { area(Processing) { action(ActionName) { ApplicationArea = All; trigger OnAction() begin end; } } } var myInt: Integer;}

Card 页面通过其 ID名称 来标识(这两个值在应用程序内部必须唯一)。页面也有自己的属性。需要定义的主要内容如下:

  • PageType: 标识页面的类型。

  • SourceTable: 设置此页面的基础表。

  • SourceTableView: 设置您希望使用的键、排序顺序和过滤器,以确定呈现给用户的源表的视图。

  • ApplicationArea: 设置页面在 Business Central 应用程序中的可见性。标准值包括 All、Basic、Suite 和 Advanced。

  • UsageCategory: 设置网页客户端中搜索页面的部门列。

  • Extensible: 设置对象是否可以扩展。

页面有一个 layout(定义页面在 UI 中的外观)和一个 actions 部分(定义可用的菜单项,以便在页面内添加代码操作)。在布局内,您有一个内容区域,其中包含一组组,且每个组可以包含一个或多个页面字段。您可以使用 tpagefield 代码段在页面组中添加字段:

field(MyField; FieldSource){ ApplicationArea = All FieldPropertyName = FieldPropertyValue;}

页面上的字段通过名称(页面中的字段关键字)和字段源(页面字段的源表达式,对应底层表中定义的物理字段)来定义。

字段可以具有自己的属性,并且必须设置ApplicationArea

List页面(第三种选项)定义如下:

page Id PageName{ PageType = List; ApplicationArea = All; SourceTable = TableName; layout { area(Content) { repeater(Group) { field(Name; NameSource) {  ApplicationArea = All; } } } area(Factboxes) { } } actions { area(Processing) { action(ActionName) { ApplicationArea = All; trigger OnAction(); begin end; } } }}

List页面的PageType属性设置为List,并且layout部分有Content区域和FactBox区域。Content区域包含一个repeater组,显示你希望在该列表上展示的所有字段。之后,你可以设置actions部分。

如果页面包含repeater控件(例如,List页面),你可以定义适用于整个页面或单个记录的操作。为此,操作有一个名为Scope的属性,可以定义为页面(操作位于页面级别)或repeater(操作位于记录级别)。

表扩展定义

正如我们之前提到的,在 Dynamics 365 Business Central 中,你不能修改现有表;相反,你需要创建一个表扩展。

可以使用ttableext片段定义表扩展:

tableextension Id MyExtension extends MyTargetTable{ fields { // Add changes to table fields here } var myInt: Integer;}

tableextension对象通过ID名称(必须是唯一的)以及必须扩展(或修改)的表来定义。然后,在字段组内部,你可以添加新字段或更改现有字段的属性。

以下代码是对标准Customer表的扩展示例,添加了一些新字段并更改了现有字段的属性:

tableextension 50100 CustomerExtSD extends Customer{ fields { field(50100; PacktEnabledSD; Boolean) { DataClassification = CustomerContent; Caption = \'Packt Subscription Enabled\'; } field(50101; PacktCodeSD; Code[20]) { DataClassification = CustomerContent; Caption = \'Packt Subscription Code\'; } modify(\"Net Change\") { BlankZero = true; } } }

tableextension对象中,你还可以通过添加keys组来向扩展的表添加新键,就像在表定义中一样。例如,在我们之前的tableextension对象中,我们添加了两个新字段,并且我们还希望在这些字段上创建一个二级键。我们可以创建一个key组,定义键名和键字段:

tableextension 50100 CustomerExtSD extends Customer{ fields { field(50100; PacktEnabledSD; Boolean) { DataClassification = CustomerContent; Caption = \'Packt Subscription Enabled\'; } field(50101; PacktCodeSD; Code[20]) { DataClassification = CustomerContent; Caption = \'Packt Subscription Code\'; } modify(\"Net Change\") { BlankZero = true; } } keys { key(PacktKey; PacktCodeSD,PacktEnabledSD) { } }}

你不能基于新字段或标准字段创建键,也不能在扩展的表中修改现有键。

在这里,我们在Customer表中定义了一个名为PacktKey的二级键,它由两个自定义字段(PacktCodeSDPacktEnabledSD)组成。定义二级键对于提高某些计算、排序记录和报告的性能非常有用。

页面扩展定义

与表一样,在 Dynamics 365 Business Central 中,你不能直接修改现有页面;相反,你需要创建一个页面扩展(使用 AL 中的pageextension对象)。

可以使用tpageext片段定义pageextension对象:

pageextension Id MyExtension extends MyTargetPage{ layout { // Add changes to page layout here } actions { // Add changes to page actions here } var myInt: Integer;}

一个pageextension对象由ID名称(必须唯一)以及必须扩展的页面定义。一个pageextension对象包含一个layout块(你可以在其中添加对标准页面布局的更改,如添加新字段或新部分,或更改标准字段)和一个actions块(你可以在其中添加新的操作)。

以下是一个pageextension对象的示例,其中我们向Customer Card页面添加了一个新字段(该字段被添加到General选项卡的末尾),并修改了现有字段(Name字段)的Style属性:

pageextension 50100 CustomerCardExtSD extends \"Customer Card\"{ layout { addlast(General) { field(PacktEnabledSD; PacktEnabledSD) { ApplicationArea = All; } } modify(Name) { Style = Strong; } } }

如你所见,我们已向页面添加了一个字段,并修改了Name字段的Style属性,使其显示为粗体。请记住,并非所有可用的字段属性都可以通过pageextension对象进行修改。

代码单元定义

代码单元是 AL 代码的容器,这些代码可以通过直接执行代码单元(使用OnRun触发器)或通过调用代码单元中定义的函数来触发。

我们可以通过使用tcodeunit片段在 AL 中定义代码单元:

codeunit Id MyCodeunit{ trigger OnRun() begin end; var myInt: Integer;}

代码单元由ID名称(在你的应用程序中必须唯一)定义。默认情况下,代码单元框架只包含OnRun触发器的定义,在此触发器中,你可以编写希望在调用Codeunit.RUN方法时执行的代码。

代码单元有其自己的属性,你可以进行设置:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/ms-ms-dyna365/img/2de302f6-93b0-4dcb-b29d-3de9bfa8e97d.png

在代码单元中,你可以定义可以是本地或全局(即公开暴露给实例化该代码单元的对象)的过程(函数)。

你可以通过使用tprocedure片段来定义一个过程:

local procedure MyProcedure() var myInt: Integer; begin end;

默认情况下,这段代码创建了一个没有参数且没有返回值的本地过程。通过移除local关键字,你可以将作用域从本地(默认值,意味着它仅在声明该过程的对象内部可见)更改为全局(使其在对象外部也可见)。

例如,这是一个带有参数和返回值的全局过程:

procedure CheckIfPacktCustomerIsEnabled(CustomerNo: Code[20]): Boolean var //Local variables here begin //Method code here end;

一个代码单元可以定义多个过程(本地或全局)。

事件定义

如前所述,事件是开发 Dynamics 365 Business Central 扩展时的基础构件。在处理事件时,我们有两个主要实体:事件发布者和事件订阅者

一个事件发布者(由应用程序引发的事件)可以通过使用teventbus(用于业务事件)或teventint(用于集成事件)片段在 AL 中定义:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/ms-ms-dyna365/img/c67bafb2-7efd-40a4-b321-8c1667fdd4d8.png

一个业务事件具有以下模式:

[BusinessEvent(IncludeSender)] local procedure MyProcedure() begin end;

在这里,IncludeSender是一个布尔值,指定包含事件发布者方法的对象中定义的全局方法是否对订阅此事件的事件订阅者方法可见(当全局方法必须可见时为true,默认为false表示不可见)。

IncludeSender参数设置为true时,订阅此发布事件的事件订阅者方法的签名将自动包含一个VAR参数(引用值),用于发布事件对象。

集成事件具有以下结构:

[IntegrationEvent(IncludeSender,GlobalVarAccess)] local procedure MyProcedure() begin end;

在这里,IncludeSender布尔参数与我们之前描述的意义相同。

GlobalVarAccess是一个布尔参数,指定是否可以访问包含事件发布者方法的对象中定义的全局变量,供订阅此发布事件的事件订阅者方法使用(当需要暴露时为true,默认值为false表示不可访问)。

GlobalVarAccess参数设置为true时,所有订阅此事件的事件订阅者方法都将能够访问事件发布者方法所在对象中的全局变量。你必须手动将变量参数添加到事件订阅者方法,并且需要使用与事件发布者对象中的变量声明匹配的名称和类型。

在事件发布者(你之前定义的方法)发布事件后,你需要在代码中适当的位置触发该事件(事件订阅者在应用程序代码中触发事件之前不会响应该事件)。

作为示例,以下是一个包含公共方法的代码单元,该方法触发业务事件和集成事件:

codeunit 50100 MyCodeunit{ procedure CheckIfPacktCustomerIsEnabled(CustomerNo: Code[20]): Boolean begin //Raising a business event MyBusinessEvent(\'XXX\'); //Other code here... //Raising an integration event MyIntegrationEvent(\'YYY\'); end; [BusinessEvent(true)] local procedure MyBusinessEvent(ID: Code[20]) begin end; [IntegrationEvent(true,true)] local procedure MyIntegrationEvent(ID: Code[20]) begin end; //Global variables var myInt: Integer; Customer: record Customer;}

事件订阅者(处理应用程序中已触发事件的函数)可以使用teventsub代码片段声明:

[EventSubscriber(ObjectType::ObjectType, ObjectID, \'OnSomeEvent\', \'ElementName\', SkipOnMissingLicense, SkipOnMissingPermission)]local procedure MyProcedure() beginend;

从上述代码中,我们可以看到以下内容:

  • ObjectType是一个枚举,标识发布事件以供订阅的对象类型(包含事件发布者方法的对象),或触发事件以供订阅的对象类型。

  • ObjectId是一个整数值,指定发布事件以供订阅的对象的 ID(声明时不要使用 ID,而是使用ObjectType::Name语法)。

  • OnSomeEvent是一个文本参数,指定由ObjectId参数标识的对象中发布事件的方法的名称。

  • ElementName是一个文本参数,用于数据库触发事件。它指定触发事件相关的表字段。

  • SkipOnMissingLicense 是一个布尔参数,用于指定当运行当前会话的用户帐户的 Dynamics 365 Business Central 许可证未包含对包含订阅者方法的对象的权限时,事件订阅者方法会发生什么(true 表示方法调用必须被忽略,false 表示必须抛出错误并停止代码执行)。

  • SkipOnMissingPermission 是一个布尔参数,用于指定当运行当前会话的用户帐户没有对包含事件订阅者方法的对象的权限时,订阅者方法会发生什么(true 表示方法调用必须被忽略,false(默认值)表示必须抛出错误并停止代码执行)。

作为一个示例,这是一个代码单元,包含我们在前面示例中定义的业务事件和集成事件的两个事件订阅者:

codeunit 50101 MySubscriberCodeunit{ [EventSubscriber(ObjectType::Codeunit, Codeunit::MyCodeunit, \'MyBusinessEvent\', \'\', false, false)] local procedure MyBusinessEventSubscriber(ID: Code[20]) begin end; [EventSubscriber(ObjectType::Codeunit, Codeunit::MyCodeunit, \'MyIntegrationEvent\', \'\', false, false)] local procedure MyIntegrationEventSubscriber(ID: Code[20]) begin end; }

在定义事件订阅者时,如果你在事件参数上按 Ctrl + 空格键,你将看到事件可以与之交互的对象列表(由发布者暴露)。在我们的示例中,业务事件订阅者可以看到事件参数和发送者对象(因为我们已将事件发布者声明为IncludeSender设置为true),如下所示:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/ms-ms-dyna365/img/a671131f-dfce-4ad3-8021-cb37b4518ff2.png

集成事件订阅者可以看到事件参数、发送者对象(因为我们已将事件发布者声明为IncludeSender设置为true),以及发送者对象的全局变量(因为我们已将事件发布者声明为GlobalVarAccess = true):

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/ms-ms-dyna365/img/d0630f16-21ce-4050-99eb-556b165df950.png

使用事件时,始终记住以下几点:

  • 当调用事件发布者方法的代码运行时,所有订阅该事件的事件订阅者方法都会被执行。

  • 如果有多个订阅者,订阅者方法将按随机顺序逐一运行(无法指定订阅者方法调用的顺序)。

  • 如果没有订阅发布事件的订阅者,那么调用事件发布者方法的代码行将被忽略,并且不会执行。

XMLport 定义

XMLport 是用于在外部源与 Dynamics 365 Business Central 之间导入和导出 XML 或基于文本的数据的对象。

可以使用 txmlport 代码片段在 AL 中定义一个 XMLport:

xmlport Id MyXmlport{ schema { textelement(NodeName1) { tableelement(NodeName2; SourceTableName) { fieldattribute(NodeName3; NodeName2.SourceFieldName) { } } } } requestpage { layout { area(content) { group(GroupName) {  field(Name; SourceExpression)  {  } } } } actions { area(processing) { action(ActionName) { } } } } var myInt: Integer;}

作为一个示例,这是一个简单的 XMLport 定义,用于导入一些客户数据(No.Name 字段):

xmlport 50100 MyXmlportImportCustomer{ Direction = Import; schema { textelement(NodeName1) { tableelement(Customer; Customer) { fieldattribute(No; Customer.\"No.\") { } fieldattribute(Name; Customer.Name) { } } } } }

xmlport 对象的 Direction 属性设置为 Import(仅用于将数据导入 Dynamics 365 Business Central),并从名为 Customer 的 XML 对象中读取 NoName 字段。

定义查询对象

query 对象允许你定义一个对象,可以通过应用过滤器和在表之间建立连接,从一个单独的表或多个表中检索数据。返回的结果是一个单一的数据集。

你可以通过使用tquery代码片段在 AL 中创建查询:

query Id MyQuery{ QueryType = Normal; elements { dataitem(DataItemName; SourceTableName) { column(ColumnName; SourceFieldName) { } filter(FilterName; SourceFieldName) { } } } var myInt: Integer; trigger OnBeforeOpen() begin end;}

如你所见,query对象有一个elements部分,在该部分内,你定义了一个dataitem及其必须检索的column元素(要包含在结果数据集中的表字段)。

你还可以在dataitems之间创建链接,以从多个表中检索数据。

作为示例,以下是一个query对象,它已在 AL 中定义,用于检索客户列表及其销售和利润数据:

query 50100 \"Customer Overview\"{ Caption = \'Customer Overview\'; elements { dataitem(Customer; Customer) { column(Name; Name) { } column(No; \"No.\") { } column(Sales_LCY; \"Sales (LCY)\") { } column(Profit_LCY; \"Profit (LCY)\") { } column(Country_Region_Code; \"Country/Region Code\") { } column(City; City) { }column(Salesperson_Code; \"Salesperson Code\") { } dataitem(Salesperson_Purchaser; \"Salesperson/Purchaser\") { DataItemLink = Code = Customer.\"Salesperson Code\"; column(SalesPersonName; Name) { } dataitem(Country_Region; \"Country/Region\") {  DataItemLink = Code = Customer.\"Country/Region Code\";  column(CountryRegionName; Name)  {  } } } } }}

查询循环遍历Customer表,然后(对于每个客户)从在DataItemLink属性中指定的其他表中检索数据。

查询对象在代码中非常有用和强大,用于检索记录。你可以通过查询对象解决的第一个基本问题是避免在从关联表(联接)中检索数据时使用嵌套循环。如果你有一个通过外键与Table1关联的Table2,那么你可以使用查询对象,避免通过循环遍历Table1并为每个记录去Table2检索相关数据,可以应用以下图示所描述的模式:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/ms-ms-dyna365/img/bf854d9f-10d7-46ff-9419-915f201d56d0.png

在这里,你可以定义一个查询,它返回两个表的完整过滤联接,然后你可以循环遍历由查询对象返回的记录集(这只需要一个循环)。

如果(例如)我们想在代码中使用之前定义的Customer Overview查询,那么我们需要在 AL 中这样做:

procedure UseCustomerOverviewQuery() var CustomerOverview: Query \"Customer Overview\"; begin if not CustomerOverview.Open() then exit; while CustomerOverview.Read() do begin //Here we have all joined records to loop end; end;

在这里,我们通过调用Open方法执行查询对象,然后通过使用Read方法循环遍历返回的数据集。在循环内,你将获得查询返回的完整记录(主表和已联接的表),并且可以根据需要处理这些数据。

扩展选项 – 枚举

选项类型的字段在 Dynamics 365 Business Central 中用于定义一个提供固定且预定义值列表的字段。

当你定义一个选项字段时,你可以通过以下方式定义该字段的允许值:

field(5; LicenseType; Option){ OptionMembers = \" \",\"Full\",\"Limited\"; OptionCaption = \' ,Full,Limited\'; Caption = \'License Type\'; DataClassification = CustomerContent;}

在前面的代码中,我们可以看到OptionMembers属性包含了字段的预定义值。在这里,许可证类型字段包含三个值(空白、完整、限制),其中空白(第一个值)是默认值。

但是,如果你想扩展这些选项,例如,添加一个新的许可证类型叫做Teams,该怎么办呢?这是不可能的!选项字段不能扩展。

为了创建一个可扩展的选项字段,AL 引入了enum对象。一个enum是由一组命名常量组成的类型,并且如果你将Extensible属性设置为true,它可以从其他扩展中进行扩展,如下所示:

enum 50100 LicenseType{ Extensible = true; value(0; None) { } value(1; Full) { } value(2; Limited) { } }

你可以按照以下方式定义一个字段,使其具有enum类型:

field(50100; LicenseType; enum LicenseType) { Caption = \'License Type\'; DataClassification = CustomerContent;}

这使得你能够定义一个字段,它的行为与选项相同:当用户点击该字段时,Dynamics 365 Business Central 会展示一个可供选择的值列表。

要从另一个扩展中扩展 enum 字段并添加一个新的可能值 Team,你需要创建一个 enumextension 对象,具体如下:

enumextension 50110 LicenseTypeEnumExt extends LicenseType{ value(50110; Team) { Caption = \'Team License\'; }}

之后,你的 License Type 字段将有一个新的选项值可以选择。

你还可以直接在 AL 代码中使用 enum 对象(作为变量):

var LicenseType: enum LicenseType;begin case LicenseType of LicenseType::Full:  //Write your code here…

你还可以扩展 enum 值的 TableRelation 属性。例如,假设你有以下表格:

table 50120 LicenseDetail{ fields { field(1; Id; Integer) { } field(2; LicenseType; enum LicenseType) { } field(3; LicenseDetail; Code[20]) { TableRelation = if (LicenseType = const (Full)) FullLicenseTable else if (LicenseType = const (Limited)) LimitedLicenseTable; } }}

在这个表中,我们有一个名为 LicenseType(这是一个 enum 类型)的字段,以及一个名为 LicenseDetail 的字段,它有一个 tablerelation 属性(指向 FullLicenseTableLimitedLicenseTable 表),其基于 enum 字段的值。

另一个应用程序可以同时扩展 enum 字段和表关系,这样它就可以处理新的扩展枚举。以下是一个示例:

enumextension 50110 LicenseTypeEnumExt extends LicenseType{ value(50110; Team) { Caption = \'Team License\'; }}tableextension 50110 LicenseDetailExt extends LicenseDetail{ fields { modify(LicenseDetail) { TableRelation = if (LicenseType = const (Team)) TeamLicenseTable; } }}

在这里,新应用程序创建了 LicenseType 的枚举扩展(如我们之前所述),并创建了一个新的 tableextension 对象,在这个对象中,它通过添加一个新的关系来修改 LicenseDetail 字段的 TableRelation 属性,当 enum 的值为 Team 时,关联一个 TeamLicenseTable

合并后的 TableRelation 始终从上到下进行评估,因此第一个无条件的关系将优先。这意味着,如果原字段与表 A 有关系,你无法将其 TableRelation 从表 A 更改为表 B。

通过使用 enums,你可以扩展所有选项的值。如果你希望具有可扩展性,我们建议在你的扩展中使用这种新方法。

在这一部分,你已经全面了解了 AL 语言扩展中的可用对象。在下一部分,我们将学习一些创建和处理 AL 项目时的最佳实践。

创建一个配置文件对象

一个 profile 对象使你能够定义特定用户配置文件的用户体验(主页)。你可以通过使用 AL 语言扩展中的 tprofile 代码片段来创建一个 profile 对象。

一个配置文件对象的定义如下所示:

profile \"SALES MANAGER\"{ Caption = \'Sales Manager\'; ProfileDescription = \'Functionality for sales managers\'; RoleCenter = 9005; Enabled = false;}

在这里,我们定义了一个名为 Sales Manager 的配置文件,它使用 RoleCenter 页面,ID = 9005(这是 Dynamics 365 Business Central 中的标准销售经理角色中心对象)。

要从你的扩展中部署一个 profile 对象,我建议在你的 AL 项目中创建一个 Profile 文件夹,并将所有定义配置文件的 .al 文件放在该文件夹内。

理解 AL 项目结构的最佳实践

正如我们之前提到的,AL 项目是基于文件的。你所有的 .al 文件都位于一个项目文件夹中。当你开始处理一个复杂项目时,最常遇到的问题就是如何组织项目。我们该如何组织对象和 .al 文件呢?

这个话题没有书面规则。我们真诚地建议避免将所有对象(.al 文件)放在项目根目录级别,如下图所示:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/ms-ms-dyna365/img/e9f8cf4b-750b-4f97-8368-cf847df4c532.png

在这里,没有对对象进行任何组织,如果您有大量对象,您的对象列表将会增长很多,导致处理和查找文件时遇到困难。

组织项目的最常见方式是按对象类型组织文件,如下图所示:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/ms-ms-dyna365/img/b7304209-a466-48b0-bcac-edf3fc7d38b8.png

这里,所有扩展的代码都在 SRC 文件夹内。然后,所有对象按类型进行组织,根据我们定义的对象(每种对象类型都有一个子文件夹)。这种组织方式使得查找对象更容易(只需进入相应的对象类型文件夹),但是这种项目结构有一个缺点:不容易识别出我们需要哪些对象来实现扩展项目中的特定业务功能。

我们建议先按功能组织项目树,再按对象类型组织,如下图所示:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/ms-ms-dyna365/img/99fc5863-4178-4171-aa26-d395a490171d.png

这里,在 SRC 文件夹中,有两个子文件夹:Functionality1Functionality2。在这些文件夹中,对象按类型组织。这是我们推荐的工作方式,这种结构有助于我们按功能查找对象。

在接下来的章节中,我们将学习如何在 AL 中命名对象,以及如何使用对象范围。

命名规范和 AL 对象范围

在为 Dynamics 365 Business Central 创建扩展时,您需要为对象分配一个数字 ID。分配对象 ID 的规则如下:

范围 用途 0 – 49,999 Business Central 基础应用程序。合作伙伴不能使用此范围。 5,0000 – 99,999 每租户扩展(希望根据客户的个别需求定制已交付解决方案的经销商)。 80,000 – 99,999 需要在开发许可证中修改权限的扩展对象。 100,000 – 999,999 用于为特定国家或地区本地化 Dynamics 365 Business Central。合作伙伴不能使用此范围。 1,000,000 – 69,999,999 注册解决方案计划 (RSP) 范围。 70,000,000 – 74,999,999 Business Central SaaS 应用程序(AppSource)。

关于文件命名,每个 .al 文件名必须以相应的对象类型前缀和对象 ID 开头,并且只能使用字符 [A-Za-z0-9]。文件命名规则(对于 AppSource 是强制要求的)应该如下所示:

  • 完整对象:..al

  • 扩展对象:.Ext.al

对于每种对象类型,您可以使用以下缩写(前缀):

对象类型 缩写(前缀) 页面 Page 页面扩展 PageExt 页面自定义 PageCust 代码单元 CodeunitTable 表扩展 TableExt XML 端口 Xmlport 报告 Report 查询 Query 枚举 Enum 枚举扩展 EnumExt

例如,以下是一些 AL 对象及其对应的文件名:

  • 表 50100 书籍 应命名为 Book.Table.al

  • 页面 50100 书籍卡片 应命名为 BookCard.Page.al

  • 代码单元 50110 书籍管理 应命名为 BookManagement.Codeunit.al

  • 页面扩展 50101 MyCustomerCardExt,扩展 客户卡片,应命名为 CustomerCard.PageExt.al

您还应该使用前缀/后缀来标识您的对象(由 Microsoft 为您保留,如下文所述)。这使您能够在扩展之间为对象命名一个唯一的方式,从而避免命名冲突。

使用前缀/后缀的规则如下:

  • 前缀/后缀必须至少为三个字符。

  • 对象/字段名称必须以前缀/后缀开始或结束。

  • 当您使用表扩展或页面扩展修改核心 Dynamics 365 对象时,前缀/后缀必须在控件/字段/操作/组级别定义。

  • 使用标题处理您想要在 UI 中显示的标签。

例如,如果您已保留 PACKT 前缀,并且想要创建一个名为 CustomerCategory 的字段,则可以使用以下有效字段名:

  • PACKTCustomerCategory

  • CustomerCategoryPACKT

  • CustomerCategory_PACKT

  • CustomerCategory PACKT

如果您想创建 客户类别 表,表对象的有效名称如下:

  • 表 70000000 PACKT 客户类别

  • 表 70000000 Customer Category PACKT

  • 表 70000000 Customer Category_PACKT

使用保留名称作为前缀或后缀完全由您选择。我们建议将其用作后缀,因为在 Visual Studio IntelliSense 中查找字段更自然(如果您在 UI 中看到的字段是客户类别,输入这些词会呈现实际字段名称及其后缀)。

这些指南对于 AppSource 是强制性的,但对于您的每租户扩展并非强制执行。我们的建议是始终遵循这些指南。

要为您的对象注册前缀/后缀,您需要发送电子邮件到 d365val@microsoft.com,并指定您希望为应用保留的名称。请记住,前缀/后缀应该是基于应用的,而不是基于公司的。

AL 编码指南工作中

在创建 AL 项目(和 .al 文件)时,请记住始终遵循这些主要指南。

.al 代码文件中,所有对象的结构必须遵循以下顺序:

  • 属性

  • 特定对象结构:

    • 表字段

    • 页面布局

    • 操作

  • 全局变量:

    • 标签(旧文本常量)

    • 全局变量

  • 方法

请记住,始终通过对象名称而非对象 ID 来引用 AL 对象。例如,以下是如何引用 Record 变量或 Page 变量:

Vendor: Record Vendor;Page.RunModal(Page::\"Customer Card\", ...);

在事件订阅者对象中,应该这样引用发布者对象:

[EventSubscriber(ObjectType::Codeunit, Codeunit::MyCodeunit, \'MyIntegrationEvent\', \'\', false, false)]local procedure MyIntegrationEventSubscriber()beginend;

那么,让我们总结一下:

  • 格式化你的 AL 代码:注意缩进和空格(它保持代码的可读性)。你可以使用 Alt + Shift + F 来自动格式化代码。

  • 保持你的 .al 文件整洁:使用代码片段时,它们会自动创建带有方法、属性、变量、触发器或你可能未使用的部分的对象骨架。请删除所有未使用的代码。一个典型的例子是表格上的触发器定义(如果你没有处理它们,可以删除)或对象中的全局变量(如果不删除,它们会导致你的应用充满 myInt: integer 变量)。

  • 方法声明:尽量保持本地化。只有在需要将其暴露给其他对象时,才使用全局方法。

  • 使用事件触发业务逻辑,但 不要在这些触发器中编写代码:将大量代码放入触发事件中,就像把大量代码放入字段验证触发器中一样。应识别你的方法并从触发事件中调用它们。

对于复杂代码,你可以开始使用 通用方法 模式:

  • 在其类(表格)中声明每个方法。

  • 每个方法都是一个独立的代码单元(封装)。

  • 仅从其类(表格/代码单元)中调用方法。

  • 每个方法的代码单元只有一个全局函数。

  • 本地函数包括以下类别(按此顺序):

    1. 主函数(一个函数;以可读流程图形式呈现的方法头)

    2. 主要业务流程(多个函数)

    3. UI 包装器(两个函数)

    4. 业务扩展(一个或多个函数提供可扩展性)

    5. 事件包装器(两个函数)

这是根据此模式组织的一些 AL 代码示例:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/ms-ms-dyna365/img/a7f27459-d4c4-42bf-bc77-8f6805fc6b2d.png

你可以在 docs.microsoft.com/en-us/dynamics365/business-central/dev-itpro/compliance/apptest-bestpracticesforalcode 上找到有关其他编码规则的更多信息。

遵守编码规则和指南对于提高代码可读性非常重要,而且这些规则中的许多是 AppSource 强制要求的。

总结

在本章中,我们探讨了使用 AL 语言进行扩展开发的基础知识,并概述了创建应用程序的主要对象(表格、页面、代码单元等)以及如何在 Visual Studio Code 中创建它们。接着,我们回顾了处理 AL 项目的最佳实践(项目组织、对象 ID、命名约定),并提供了编写更好代码的指南,重点关注我们扩展的可扩展性方面。

我们学习了如何创建对象,如何创建 AL 项目,如何处理其结构,以及如何遵守对象命名规范。

在下一章,我们将通过应用所有这些规则和最佳实践,为 Dynamics 365 Business Central 实现一个现实世界的扩展。