慣性聚合 高效追蹤和閱讀你感興趣的部落格、新聞、科技資訊
閱讀原文 在慣性聚合中打開

推薦訂閱源

博客园 - 司徒正美
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)
D365 F&O 中的權力鏈:三個生產陷阱
SapotaCorp · 2026-05-24 · via DEV Community

命令鏈變成了與的自定義的預設模式,因為疊加方法是不持續的——每一個版本更新都會破壞某些功能,而合作夥伴則花費他們的升級預算來修復那些本應設計為向前兼容的自定義功能。CoC讓擴充套件可以藉由next()包裝基底方法,完全跳過疊加的舞蹈。

此機制需要一個小時來閱讀。三種失敗模式在生產中經常出現到足以記錄的程度.

陷阱 1: 當增強時忘記 next()

剛接觸協作協議的團隊經常編寫看起來像這樣的驗證擴展:

[ExtensionOf(tableStr(SalesTable))]
final class SalesTableExt_Extension
{
    public boolean validateWrite()
    {
        if (this.CustomCheck == NoYes::No)
        {
            return checkFailed("Custom check failed");
        }
        return true;
    }
}

進入全螢幕模式 退出全螢幕模式

錯誤:沒有next validateWrite() 的呼叫。基底方法從不執行,因此所有庫存驗證都靜默消失。僅運行自訂檢查路徑的單元測試會通過。遺失的基底驗證直到基底本應拒絕的數據成功傳遞到生產環境時才會浮現。

當意圖是添加邏輯而非替換時,先呼叫 next() 再合併結果:

public boolean validateWrite()
{
    boolean ret = next validateWrite();
    if (ret && this.CustomCheck == NoYes::No)
    {
        ret = checkFailed("Custom check failed");
    }
    return ret;
}

Enter fullscreen mode 退出全螢幕模式

略過 next() 是有時合法的 - 但它應該是故意的、有註解的,並且需要被檢查。無意的略過是隱藏數據完整性錯誤的地方.

陷阱 2:選擇錯誤的生命週期鉤子

FormDataSource.init() 在記錄載入之前運行。擴展代碼那麼讀取this.cursor() 或假設記錄上下文會拋出錯誤或行為不可預測。發布動態過濾器的團隊通常會將邏輯放在 init(),因為那是他們看到的第一个鉤子,然後當用戶在空數據集打開表單時第一次導致崩溃。

表單級生命週期鉤子每個都有其目的:

  • init() - 表單級設置,尚未有數據
  • executeQuery() - 查詢構建之後,在獲取之前
  • active() - 在數據來源上記錄被激活後
  • 事件前/後處理器在 executeQuery - 變更查詢的最潔淨方式,不覆蓋基本方法

從參數表中動態篩選,在 executeQuery 上的事件前處理器允許您使用事件參數中可用的數據上下文來修改查詢的範圍。無崩溃,無基本方法覆蓋,無脆弱的下游耦合。

避坑三:嘗試存取私有或受保護的成員

CoC擴充套件無法存取基底類別的私有或受保護成員。從疊蓋時代過渡過來的開發者會首先遇到這個問題:&O

[ExtensionOf(classStr(SalesLineType))]
final class SalesLineTypeExt_Extension
{
    public boolean checkPrice()
    {
        // Compile error: _commonPricing is protected
        return this._commonPricing.checkMyThing();
    }
}

進入全螢幕模式 退出全螢幕模式

微軟的擴充套件框架文件記錄了四種選項:

  1. 可掛鉤的基本方法 - 如果私有的行為透過一個公開方法呈現,就呼叫那個方法
  2. 兄弟類別存取 - 偶爾一個公開類別會暴露足夠你所需要的
  3. 在透過args暴露資料的方法上的事件處理程序 - 最乾淨的路徑
  4. 透過LCS問題搜尋請求存取 - 微軟已回應合作夥伴在連續的 One Version 發布中所提出的許多成員申請.

伸手去尋求反覆思考是錯誤的答案。它有效,直到下一次編譯改變成員佈局,而你又回到了覆蓋層級的脆弱.

調試一個靜態擴展

最令人沮喪的CoC失敗是那個編譯、部署但在執行時什麼也不做的擴充套件。在可正常運行的F&O代碼庫的審查中出現的根原因:

  • [ExtensionOf]屬性指向了錯誤的目標 - 在formStr() / tableStr() / classStr()中出現了拼寫錯誤。
  • 擴充套件類別沒有final - CoC所必需的。
  • 方法簽名不完全匹配 - 參數類型不匹配會靜默跳過。
  • 包含擴展的模型不在目標環境的模型列表中。

基本診斷步驟:在方法頂部刪除 info("hit"),重新編譯,執行場景,檢查Infolog。如果沒有出現任何內容,則上述其中一項是錯誤的。

代碼審查作為保險

運作健康的F與O代碼庫的團隊會用一個PR時期的清單來處理CoC擴展:next()被正確調用,選擇了合適的生命週期鉤子,沒有嘗試訪問私有成員,透過SysTest進行單元測試覆蓋。每個PR的十五分鐘是保險政策,確保One Version更新不會變成週末停機。