NET組件是什麼
組件的定義有多種
但最常見有幾種
組件是可互換的軟件部分
它既是工業化系統的產物
也是工業第系統的動力
在
NET平台的組件層中
組件是以Assemblies的形式創建的
NET平台創建了組件
並將組件作為其基本的元素
從本質上看
NET平台組件是一個用任何
NET語言以插件形式開發的可互換的軟件部件
它可以與其他應用程序實現互操作
使用COM+服務的
NET組件被稱作服務化組件
以示與
NET中標准的可管理組件的區別
強命名
NET組件
下面我們將討論強命名組合體(
NET組件)是什麼
當開發可配置類時
它必須被編譯
在編譯代碼後
有二方面的事情需要考慮
第一
COM+集成要求被編譯的組合體必須被強命名
我們必須通過運行被稱為sn
exe的強命名工具生成一個密碼
以生成一個強命名的組合體
一旦編譯了強命名的組合體
必須使用System
Reflection名字空間中一個被稱作AssemblyKeyFileAttribute的組合體級的屬性調用存儲在文件中的該密碼
#using
using System;
using System::EnterpriseServices;
using System::Reflection;
[assembly: ApplicationName(
FirstApp
)]
[assembly: ApplicationActivation(ActivationOption
Library)]
// AssemblyKeyFile屬性調用由sn
exe生成的密碼文件
組合體將擁有強命名
[assembly: AssemblyKeyFile(
thiskeyfile
)]
namespace ESExample
{
???
}
第二
在編譯強命名的組合體時
必須調用輸出System
EnterpriseServices名字空間中類型的組合體━━System
EnterpriseServices
dll
下面是生成密碼和編譯可配置類的命令
sn
k thiskeyfile
Cl /out:ThisExample
dll /t:library
/r:System
EnterpriseServices
dll FirstCfgClass
cpp
在COM+中注冊
NET組件
COM+有二種注冊方式
動態方式和手工方式
這二種方式都相當簡單
但對於本例
動態方式是合適的
動態注冊方式還有一些要求
組合體必須是強命名的
組合休可以不在全局性的組合體緩沖區中
組合體必須被可管理的(
NET)客戶端使用
組合體激活類型必須是Library
初看起來
似乎限制相當嚴格
但其實它包括多種情況
讀者一定在想
激活類型必須是Library
但還沒有創建過Library COM+組件呢
在
NET中
服務組件的客戶端在同一台計算機上
或者客戶端將遠程訪問代理應用程序
以訪問COM+組件
因此
純
NET解決方案將在大多數情況下使用動態注冊方式
在客戶端第一次實例化服務化組件時
就會進行動態注冊
而且對於每個版本的組合體而言
只會注冊一次
我們需要注意COM+目錄更新和組件第一次被訪問之間在時間上的滯後
代碼將跟蹤內存中對象的數量以及在一定的活動期間及其之後仍然有多少對象仍然是活動的
注意
在對對象進行初次調用後
系統中存在一個有
個對象的緩沖池
似乎是一旦一個對象被實例化
在有方法被調用之前
它一直是活動的
一旦有方法被調用
該對象就只在調用期間是活動的
這也提醒我們
在准備使用對象之前
盡量不要去招惹它們
移植的策略
在決定將部分或全部現有的應用軟件移植到
NET環境中
就需要決定哪種移植方法最適合你
本篇文章介紹了水平移植和垂直移植二種應用軟件的移植方式
水平移植和垂直移植
水平移植是指取代應用程序中的全部一個層
例如
可以選擇取代基於Web的表示層中的ASP代碼或選擇取代中間層中的COM代碼
垂直移植指的是替換一個應用程序中所有n層中的一部分
組件設計
本篇文章提出了一些與向
NET/COM移植和組件設計互操作性問題方面的普遍原則
通過互操作層在
NET和 COM環境之間進行互操作時
CCW或RCW(依據調用的方向而不同)必須在二個環境之間的調用棧中對數據進行轉化
有些數據類型無需轉換
包括整型
長整型和浮點型數據類型在內的通用性數據無需轉換
而非通用性數據則需要轉換
Visual Basic的BSTR是非通用性數據類型的一個例子
在向
NET移植應用程序之前
應該在可管理性和非可管理性代碼之間盡量少地使用非通用性數據類型
原因是相關的轉換代價將影響到應用程序的性能
通用數據類型
大多數的數據類型在可管理性和非可管理性內存中的表示都相同
互操作層無需作特別的處理
由於在可管理和非可管理代碼之間無需轉換
因此這些數據類型被稱作通用類型
整型和浮點型數據是通用類型數據類型
由通用型數據類型組成的數組和結構也是通用型數據類型
非通用數據類型
非通用數據類型在可管理和非可管理語言中的表示是不同的
由於當在可管理性和非可管理性代碼之間進行互操作時
它們要求互相轉換
因此被稱作非通用型數據類型
例如
由於有幾種不同的非可管理性表示
其中的一些可能需要進行轉換
因此
可管理的字符串是非通用型數據類型
字符串
日期
對象是非通用型數據類型的例子
在執行互操作時
它們都需要轉換
現有的COM組件和可管理客戶端
在向
NET平台移植應用程序時
需要考慮現有的COM組件所使用的界面
盡管會不再使用現有的COM客戶端
仍然會在
NET客戶端中使用現有的COM組件
因此
在設計界面時
應該如何既考慮到二種環境中現有的組件也要考慮到未來的可管理客戶端
在向
NET移植組件時
需要使用tlbimp工具自動地生成一個應用程序的RCW
缺省情況下
RCW使用與現有組件相同的界面(通過定義相同和屬性和方法)
在許多情況下
傳統的COM類型的界面並不是天生地從可管理性代碼中使用的
可管理性代碼開發人員將能夠充分地利用下面的特性
·參數化的構造器
·繼承
·靜態方法
我們應當考慮編寫一個COM對象使用的自定義包裝類
向可管理客戶端提供這些能力
創建更適合可管理代碼環境的界面
包裝類在內部使用COM組件的RCW
並代理對現有COM組件的大多數調用
一些調用能夠完成更復雜的數據類型轉換工作
例如
ADO
NET數據集和ADO記錄集之間的映射
此後
我們可以將更多的功能從COM組件轉移到包裝類中
而不會影響可管理代碼
在決定是使用RCW或自定義的可管理性包裝類時
有許多因素需要考慮
需要注意的是
TlbImp工具能夠將COM類型庫轉換為
NET架構元數據
一旦類型庫被轉換為元數據
可管理客戶端可以無縫地調用COM類型
為了簡化使用
我們總是在類型庫中提供類型信息
如果組件有大量的已經習慣了現有對象模型的客戶端
創建RCW和使用現有的界面就是一個比較合適的策略
Excel中的對象模型被使用VBA的Excel開發人員廣泛使用
對象模型是高度結構化的
並且能夠很好地映射由Excel提供的特性和用戶界面
客戶非常熟悉現有的對象模型
如果對象模型發生大幅度的變化
用戶就需要進行大量的訓練
在本例中
使用標准的RCW可能是合適的
在編寫COM界面的自定義的可管理包裝類時
這些界面將被通過RCW從可管理性代碼中調用
每個屬性調用都需要有互操作層的參與
會帶來一定的代價
對於一個只作很少工作的簡單界面來說
互操作造成的代價將是
條匯編指令
對於完成大量工作的方法而言
這點代價是微不足道的
但對於一個簡單的屬性訪問而言
這一代價還是太大了
如果在不久之後要將COM組件的客戶端移植到
NET平台上
在考慮編寫自定義的可管理包裝類時
應當將界面的功能由COM組件轉到包裝類中
否則
可以在COM對象中實現界面
並被代理到可管理的包裝類中
通過重新安排代碼
我們能夠使互操作層的代價最小
並擁有一個從可管理代碼到對象的最簡單自然的界面
編寫自定義的可管理包裝類的帶來的另一個好處是可以移動遠程對象的分界線
類的界面的實現
在可管理代碼中
類的界面的定義並不是顯性的
該界面包含適用於
NET對象使用的所有公共方法
屬性
域和事件
它可以是一個雙重或者僅起調度作用的界面
類界面的名字為
NET類名字前加一下劃線
例如
對於Mammals而言
類界面的名字是_Mammals
對於派生類而言
類界面也需要實現基本類所有的公共方法
域和屬性
派生類還實現每個基本類的界面
例如
Mammals類擴展了類MammalMainclass
NET對象向COM客戶端提供三個名字為_Mammals
_MammalMainclass和_Object的界面
COM客戶端能夠獲得名字為Mammals的類界面
該界面定義在由類型庫輸出向導(Tlbexp
exe)工具生成的類型庫中
如果Mammals類實現一個或多個界面
這些界面將出現在coclass中
[odl
uuid(
)
hidden
dual
nonextensible
oleautomation]
interface _Mammals : IDispatch
{
[id(
x
)
propget] HRESULT ToString([out
retval] BSTR*
pRetVal);
[id(
x
)] HRESULT Equals([in] VARIANT obj
[out
retval]
VARIANT_BOOL* pRetVal);
[id(
x
)] HRESULT GetHashCodes([out
retval] short* pRetVal);
[id(
x
)] HRESULT GetType([out
retval] _Type** pRetVal);
[id(
x
d)] HRESULT EatIt();
[id(
x
e)] HRESULT GetBreathe();
[id(
x
f)] HRESULT GoSleep();
}
[uuid(
)]
coclass Mammals
{
[default] interface _Mammals;
}
類界面生成是可選的
如果沒有選擇其他選項
COM互操作層為每個輸出到類庫中的類生成一個只起調度作用的界面
通過在類中添加ClassInterfaceAttribute屬性
我們可以中止或修改這一界面的自動創建
盡管類界面能夠使我們無須向COM提供可管理
From:http://tw.wingwit.com/Article/program/Java/hx/201311/26363.html