慣性聚合 高效追讀感興趣之博客、新聞、科技資訊
閱原文 以慣性聚合開啟

推薦訂閱源

博客园 - 司徒正美
V
V2EX
T
Tailwind CSS Blog
有赞技术团队
有赞技术团队
aimingoo的专栏
aimingoo的专栏
Apple Machine Learning Research
Apple Machine Learning Research
IT之家
IT之家
Blog — PlanetScale
Blog — PlanetScale
A
About on SuperTechFans
月光博客
月光博客
T
The Blog of Author Tim Ferriss
宝玉的分享
宝玉的分享
Martin Fowler
Martin Fowler
博客园 - 聂微东
The GitHub Blog
The GitHub Blog
V
Visual Studio Blog
WordPress大学
WordPress大学
酷 壳 – CoolShell
酷 壳 – CoolShell
Engineering at Meta
Engineering at Meta
GbyAI
GbyAI

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python)
企业中心AL扩展:按租户划分与AppSource路径之别
SapotaCorp · 2026-05-24 · via DEV Community

中市场分销商多采用 Business Central,每于定制工程既毕,辄问同:其工当作租户扩展以运,抑或作 AppSource 应用以售于类己之分销商乎?技业几无别。然 ALM、支援模态、商案则迥异。

AL 扩展者何也

商業中心之定制,乃AL碼以擴充形式裝束。AL者,BC專屬之語言,似TypeScript而異於X++。擴充可藉由事件與處理器,增頁面、表、報表佈局、API終點及商業邏輯。

現代BC(SaaS)之每一定制,必為擴充。直修改基礎碼者,不可為。此與舊NAV相反,彼時夥伴輸出客戶分支之碼。

按租户发布

按租户发布者,乃构作.app之文件,经管理员中心或PowerShell,上传于特定客户之BC环境,独运行于彼处。

利处:

  • 无需微软审查周期——同日即可发布更新
  • 支持时直抵客户数据
  • 依客定价,界面定制,业务逻辑无通用抽象

弊:

  • 每客独维,永无休止
  • 无自动更新,每客环境需手动发布
  • 无市集可见
  • 收入为计费咨询,非产品

按户定制咨询:客欲其规,客所费于制,代码之属归于客.

AppSource发布

AppSource乃微软之市集。尔建同款.app,纳于微软,经验而合,遂可自目录中为BC客所安装.

利处:

  • 一代码,众客用
  • 由微软内容分发网络自动分发
  • 订阅许可之续收其利
  • 市场之SEO与显见

缺:

  • 微软审阅之期:每提呈二至八周
  • 严核之验:命名之缀,对象之域,测试之覆,每户之设
  • 无会话则于支持中不得触客户之数据
  • 功能之工迟缓,因变体之配置,缓迭代之速

AppSource合产品之思:规可通,市有多客,经可行于订阅

技术之设若同

无论租户独用或AppSource,AL项目之结构同:

app.json              # Manifest: publisher, name, version, dependencies, idRanges
.vscode/launch.json   # Connection to test sandbox
src/
  Tables/             # Table objects
  Pages/              # Page objects
  Codeunits/          # Business logic
  Reports/            # Report definitions
  APIs/               # Custom API endpoints
  Enums/              # Enumerations
test/
  Codeunits/          # Unit tests

入全景模式 出全景模式

app.json显者,控制之文也。出版者、名、版次及ID之范围,皆在焉。于AppSource,此必合于注册之AppSource开发者档案及所赋之ID范围(通常为ISVs之50000-99999)。

依賴管理

一插件可依微软之基础应用、系统应用,或他插件。宣告其依存于app.json

"dependencies": [
  {
    "id": "437dbf0e-84ff-417a-965d-ed2bb9650972",
    "publisher": "Microsoft",
    "name": "Base Application",
    "version": "24.0.0.0"
  }
]

进入全屏模式 退出全屏模式

版本锁定甚为要紧。宜锁定最低所需版本。若锁定过严,则令客滞于旧版BC。若锁定过宽,则吾之扩展调用彼处旧版不存之API。

于AppSource,兼容性声明("application": "24.0.0.0"已验证:微软检验汝已测试于所声明之范围。

事与应者

AL无若X++之直接统御链。其事乃为上品。微软于基码之要处发事,汝当订阅之:

codeunit 50100 "MyCustomerExt"
{
    [EventSubscriber(ObjectType::Table, Database::Customer, 'OnAfterInsertEvent', '', false, false)]
    local procedure OnAfterCustomerInsert(var Rec: Record Customer)
    begin
        if Rec."Customer Group Code" = 'PREMIUM' then
            // Custom behavior
    end;
}

入全景模式 出全景模式

订阅模式较之X++ CoC,有其一清之长:订阅者无需识其方法之签。然其弊在:若微软未布所需之事件,则困顿矣,或须通过AL反馈门户请之。

测试之器已发

每AL之延,皆自运其测试之器。测试乃代码之单元,具[Test]

codeunit 50101 "MyCustomerExtTests"
{
    [Test]
    procedure PremiumCustomerGetsDiscount()
    var
        Customer: Record Customer;
        Discount: Decimal;
    begin
        Customer."Customer Group Code" := 'PREMIUM';
        Customer.Insert();
        Discount := CustomerExt.CalculateDiscount(Customer);
        Assert.AreEqual(10.0, Discount, 'Premium customer should get 10% discount');
    end;
}

Enter full screen mode 退出全屏模式

就AppSource而言,微软要求公共程序测试覆盖率≥80%。至于按租户划分,标准则由人定——然经验之师持同尺度,盖因不如此,则夜半必闻支持之唤.

管道部署

Azure DevOps统理二途:

  • 构建al-go或定制PowerShell调用alc.exe
  • Package:以AppSource证书签署.app文件(AppSource必需,租户可选)
  • 按租户部署:通过BC Admin Center API以PowerShell发布至客户环境
  • 部署AppSource:上传至Partner Center,微软验证,客户自动更新

至高分销商产品化之策,当先为各户独运,继而待第三、四分销商求同此功能,乃产品化之。各户之利,资于AppSource之润色。

前路之择

导引各户与AppSource之问:

  • 商业规则,独适此客乎?→ 各户之途。
  • 可否通用于业界?→ AppSource
  • 客户欲否拥有其码?→ 按户分设
  • 有无复售市场,十客以上?→ AppSource
  • 更新周期,由客或产程所驱?→ 按户分设与AppSource各别

若此误,则或为独造之过工(租户之务困于泛泛之抽象),或为产品之过简(需客制之补丁之AppSource应用)。

每有BC扩展所附之具

无论何途,一BC之延展备产者,必具:名号冠以AL之规,测试覆盖率逾八成,自动化发布之CI管路,基于事之延展(俾客得延尔之延),及载配置之README。

户别之版乃可分叉之咨询产出。AppSource之版乃产品。二者同栖一技之基。