有關(guān)Office的對(duì)象模型

字號(hào):

Office 應(yīng)用程序可以公開(kāi) COM 接口。例如,雖然您可以專(zhuān)注于 Word Document 對(duì)象并以邏輯方式獨(dú)立地實(shí)例化該對(duì)象,但在實(shí)際中會(huì)執(zhí)行 Word 進(jìn)程來(lái)提供此對(duì)象。但如果您確實(shí)需要一個(gè)開(kāi)發(fā)平臺(tái),那么雖然在某種特定情況下您只使用一個(gè)組件,您仍然會(huì)希望該平臺(tái)的其余部分保持可用。您希望該組件使用所需的任何其他平臺(tái)服務(wù),而不必親自手動(dòng)實(shí)例化這些服務(wù)。
    在 Office 解決方案環(huán)境中,哪里適合進(jìn)行組件化?許多客戶(hù)構(gòu)建其自己的特定于域、可重復(fù)使用的組件,并將其放在 Office 的上層。例如,特定于某種投資銀行業(yè)務(wù)功能的組件可能會(huì)使用 Excel 計(jì)算引擎。此組件的解決方案端接口是特定于域的,而平臺(tái)端接口則特定于 Excel。這種抽象允許該組件針對(duì) Excel 的多個(gè)版本進(jìn)行工作,而這通常恰恰是客戶(hù)所要求的。
    或者,您可以構(gòu)建一個(gè)可重復(fù)使用、不影響宿主應(yīng)用程序的通用組件。例如,看一看 UserControl,它使用 Web Services 在自定義任務(wù)窗格中顯示數(shù)據(jù)。這個(gè)控件可以在多個(gè) Office 應(yīng)用程序中重復(fù)使用。
    Office 應(yīng)用程序隨著時(shí)間的推移已經(jīng)發(fā)生了演變,它們具有非常不同的功能集,因此不可避免地提供不同的對(duì)象模型。盡管如此,但應(yīng)用程序之間仍然存在一些一致性。例如,對(duì)象模型大多具有層次結(jié)構(gòu),并且根位置通常具有一個(gè) Application 對(duì)象。在 Word 中,您可以從該 Application 對(duì)象開(kāi)始查找 Documents 集合,深化各個(gè) Document 對(duì)象,然后深化各個(gè) Range 對(duì)象。同樣,在 Excel 中,您可以從 Application 對(duì)象開(kāi)始下移到 Workbooks 集合,找到該集合中的 Workbook 對(duì)象,然后獲取工作簿中的各個(gè) Range 對(duì)象。
    此外,Visual Studio Tools for Office 還在一致的強(qiáng)類(lèi)型化對(duì)象模型上進(jìn)行分層。您只需看看兩個(gè)截然不同的 Visual Studio Tools for Office 解決方案(例如基于 Excel 文檔的解決方案和基于 Outlook 應(yīng)用程序的解決方案),就可以了解其一致性。兩個(gè)解決方案都具有簡(jiǎn)單的 Startup 和 Shutdown 方法,因此,您可以集中精力于業(yè)務(wù)需求,而無(wú)需考慮宿主應(yīng)用程序的各個(gè)特征。在仍然可以完全訪(fǎng)問(wèn)基礎(chǔ)對(duì)象模型的同時(shí),您還可以選擇在更高的抽象級(jí)別下進(jìn)行工作。
    Office 的每個(gè)新版本都保持了非常高的向后兼容性。Office 應(yīng)用程序是 COM 服務(wù)器程序,COM 提供了多個(gè)規(guī)則(如接口永久性),從而防止出現(xiàn)版本不兼容問(wèn)題。Office 通常按照這些規(guī)則運(yùn)行。所有 Office 接口都要么為雙接口,要么為純調(diào)度接口。純 vtable 接口(通過(guò)擴(kuò)展,也包括雙接口)為永久性接口,但調(diào)度接口不是,因?yàn)榭梢栽谶\(yùn)行時(shí)(因而也在后期綁定)發(fā)現(xiàn)其可用功能集和簽名。在發(fā)布新版本時(shí),Office 團(tuán)隊(duì)通常會(huì)利用這一特點(diǎn)向接口的末尾添加額外的方法和屬性。他們通常還會(huì)向現(xiàn)有的方法中添加新的可選參數(shù)。通過(guò)這些技術(shù),Office 可以保持向后兼容性。
    保持版本復(fù)原能力的另一種技術(shù)是使用松散類(lèi)型化。典型的示例為 COM 加載項(xiàng)必須實(shí)現(xiàn)的 IDTExtensibility2 接口。當(dāng) Office 應(yīng)用程序加載某個(gè)加載項(xiàng)時(shí),該應(yīng)用程序?qū)⒄{(diào)用 IDTExtensibility2::OnConnection,并傳入表示宿主應(yīng)用程序的松散類(lèi)型化對(duì)象。在 .NET 代碼中,此參數(shù)的類(lèi)型為 System.Object,而在 C++ 中,它是一個(gè)通用的 IDispatch 指針。在運(yùn)行時(shí),它實(shí)際上是指向由宿主應(yīng)用程序所提供的 Application 對(duì)象的指針。在構(gòu)建傳統(tǒng)的共享加載項(xiàng)時(shí),向?qū)傻拇a對(duì)宿主沒(méi)有任何影響。這具有兩方面的好處:它允許該加載項(xiàng)在支持 COM 加載項(xiàng)的任何應(yīng)用程序中運(yùn)行,并允許該加載項(xiàng)在任何這類(lèi)應(yīng)用程序的任何版本中運(yùn)行。
    這種對(duì)宿主無(wú)影響的模型的缺點(diǎn)是松散類(lèi)型化和后期綁定通常所具有的缺點(diǎn):不能為所涉及的特定類(lèi)型提供設(shè)計(jì)時(shí)或編譯時(shí)支持,因?yàn)檫@些類(lèi)型在運(yùn)行時(shí)以前是未知的。這極易使編寫(xiě)的代碼在運(yùn)行時(shí)失敗。另外,后期綁定會(huì)帶來(lái)性能降低,因?yàn)槊總€(gè)方法調(diào)用都必須完成發(fā)現(xiàn)過(guò)程,以確定是否確實(shí)能夠在運(yùn)行時(shí)找到匹配的方法。
    在使用 .NET Framework 開(kāi)發(fā)加載項(xiàng)時(shí),可以繼續(xù)使用此松散類(lèi)型化,但除非加載項(xiàng)本身只提供對(duì)宿主無(wú)影響的功能,否則所具有的優(yōu)勢(shì)將十分有限。只要加載項(xiàng)需要提供特定于宿主的功能,您就有可能使用宿主的特定于版本的主互操作程序集 (PIA)。另外,您還可以使用 Visual Studio Tools for Office 通過(guò) .NET 代碼構(gòu)建加載項(xiàng)。Visual Studio Tools for Office 強(qiáng)制要求強(qiáng)類(lèi)型化,不但可以為您帶來(lái)編譯時(shí)類(lèi)型檢查的好處,還可以為您帶來(lái)設(shè)計(jì)時(shí) IntelliSense® 和自動(dòng)完成的好處。強(qiáng)類(lèi)型化可避免后期綁定所帶來(lái)的性能開(kāi)銷(xiāo)。
    強(qiáng)類(lèi)型化是否意味著喪失版本的復(fù)原能力?不一定。您可以針對(duì)某一版本的 Office 構(gòu)建一個(gè)松散類(lèi)型化的加載項(xiàng),該加載項(xiàng)幾乎肯定可以在更高版本的 Office 中完全正常地工作。使用 .NET Framework 時(shí),雖然行為會(huì)稍稍復(fù)雜一些,但您可以得到同樣的結(jié)果。針對(duì)特定版本的 Office PIA 構(gòu)建的 .NET 加載項(xiàng)也應(yīng)能在更高版本中正常工作。實(shí)際上有兩種方法可以實(shí)現(xiàn)這一點(diǎn):加載項(xiàng)使用構(gòu)建時(shí)所針對(duì)的 PIA 版本,或者為 PIA 部署綁定重定向,以便加載項(xiàng)在運(yùn)行時(shí)使用對(duì)應(yīng)于所安裝的 Office 版本的更高版本的 PIA。