com

使用Delphi来跟我学COM (第一部 基本知识)  欢迎大家的光临... ... (36分)
分类:新作发表 Tense (2001-11-07 16:38:00)  
第一章 在Delphi中使用接口

1.1 定义接口:
目的:什么是接口,以及和抽象类的关联以及不同点。
抽象类(备注理解接口最简单的方法)
永远不能创建一个抽象类的实例;
本身不能实现功能,依靠派生类实现;
接口
被申明为interface类型。接口名从字母I开始。类类型名从T开始。
所有的接口从IUnknown继承;
不能创建接口实例;
不能在接口中指定范围指示。所有的方法都是公有型(public),不能在接口中申明包括范围指示;
不能申明变量;接口只能决定提供什么样的功能,对于如何完成功能没有限制;
接口中申明的所有函数和过程,概念上都是虚抽象函数和过程;因此申明时不能带Virtual;
接口是不变的;
1.2申明一个接口
目的:如何声明一个接口
常用的接口:CLSID、IID、和LIBID;
GUID(Globally Unique Identifier)全球唯一标示符: CoCreateGuid产生(API);
CLSID(Class Identifier): 代表COM对象的类别,代表COM对象的CoClass;
IID(Interface Identifier): 代表一个COM对象的接口;
例如:如何建立COM对象的方法;
   var
     iRoot: IUnkown;
   begin
     ...
     iRoot := CreateComObject(ProgIDToClassID('Project1.Interface1')); //取得实体样例
     ...
   end;
应用程序在内存中建立了COM对象的实体样例;
注意: CreateComObject回传的是COM对象的实体样例的IUnknown接口;
APPID(Application Indentifier): 应用程序ID;
CATID(Category Identifier): COM组件实现的组件类型;
LIBID(Library Identifier): COM对象实现的Type Library代表的ID;
ProgID: 有意义的字符串代表特定的CLSID;
1.3 实现接口
目的:如何实现接口
实现IUnknown: QueryInterface、 _AddRef、 _Release
使用TInterfaceObject来自动实现Iunknown,否则的话自己要实现上面的方法。
创建、使用及销毁接口: create;指向接口的指针不访问任何信息;自动释放、强迫销毁一个接口将变量置为nil
注:delphi自动创建和销毁接口。
获取单个接口的指针:
直接分配:类与他们实现的接口类型兼容的
GetInterface(const IID: TGUID; out obj):判断对象是否支持一个接口
as操作符: 对象支持特定的接口(对象不支持接口就错的话,可以拦截错误);
as自动调用计数功能;
 
1.4 高级多级接口问题
目的:在一个类中实现多个接口
在一个类中实现多个接口
TXY = class(TInterfacedObject, IXX, IYY): 类TXY 实现了IXX和IYY接口的所有方法。
多个接口不是多重继承:TXY有且只有一个基类TInterfacedObject;
方法分辨字句:当接口方法在类中实现时,方法分辨子句可使用改变他的名称
TXY = class(TInterfacedObject, IXX, IYY)
procedure IXX.pxy = pxy1
procedure IYY.pxy = pxy2

接口授权:一个接口的实现授权给另一个类:一个类包含针对另一个类的指针。
内部类: 实现一个或多个接口的功能性;
外部类: 简单的将这些方法传递给内部类,而不是重新实现接口;
 
接口属性:可以定义只读、只写、或者读写属性;
但是所有访问都必须通过访问函数,因为接口不能定义存储。 
1.5 小结
目的:如何在delphi应用程序中内部使用接口,了解delphi语言要素的接口。
申明一个接口; 
在类中实现接口; 
实现IUnknown所需要的功能; 
自动对象析构的处理; 
在类中实现多个接口; 
将一个接口的实现授权给一个内部对象; 
定义并实现接口属性
[第一章 接口][第二章 接口与COM][第三章 类型库][第四章 自动化][第五章 ActiveX][末尾]
第二章 接口与COM
2.1 GUIDs 和 COM
目的:
CLSID: Class ID是GUID一个具体的类型的名称,注册表 HKEY_CLASSES_ROOT\CLSID
每个接口CLSID或GUID都代表一个COM接口的实现 
COM对象: TCOMObject继承(TInterfacedObject不提供实现COM对象的必要功能)
Hresult: 特殊类型的返回值,意味着函数调用成功还是失败。
OleCheck: 检查函数调用可能产生的错误;当调用返回HResult的COM函数时应使用该函数;
类厂(Class Factory):
COM对象不是由程序直接例示的;
COM使用类厂来创建对象;
类厂是一个对象,目的就是创建其他对象;
每一个COM都有一个相关的类厂,负责创建在服务器中实现的COM对象;
类厂把COM从实际构造一个对象的过程中分离出来,COM没有对象构造过程
类厂支持IClassFactory接口: IClassFactory只定义2个函数CreateInstance和LockServer
CreateInstance函数: 负责创建类厂涉及的COM对象的实例的函数;
LockServer: 保持服务器在内存中,一般不要调用他;
类厂中的双重类:
2.2 进程内的COM服务器(In-Process COM Server)
目的:理解进程内的COM服务器
共性:有一个InprocServer32的子键、所有进程内服务器都输出以下四个标准函数;
DllRegisterServer: 2种方式自动调用
IDE的Register ActiveX Server菜单
Windows的命令行应用程序RegSvr32.exe(或Boland应用程序TRegSvr)
DllUnregisterServer: 是DllRegisterServer的逆进程,移走放在注册表中的条目;
DllGetClassObject:
负责提供给COM一个类厂,该类厂用语创建一个COM对象;
每个COM服务器将实现它输出的每个COM对象的类厂;
DllCanUnloadNow: 返回S_True,CO在内存中移走COM服务器;如果返回S_False
 
线程支持(Threading Support): 只适用于进程内服务器;被保存在注册表中;线程模型如下
Single-Thread Apartment(STA): 实际上根本没有线程支持,所有对COM服务器的访问由Windows顺序执行,不必考虑同步存取的问题。
Mutli-Threaded Apartment(MTA): 允许同时有多个线程存取COM对象,必须控制不同线程同步存取的程序代码;
Both Apartment: 可以执行在MTS或STA中;
自由的:
注册服务器(registering the Server): 所有的COM服务器都需要Windows注册表来工作。 
定制构造函数(Custom constructors): delphiCOM对象的基类包括一系列的非虚构造函数。
只需重载Initialize方法;
不要试图重载一个COM对象的构造函数;
创建一个进程内COM对象
function CreateComObject(const ClassID: TGUID): IUnknown;
CoCreateInstance内部创建负责创建COM对象类厂的实例,然后使用类厂来创建对象,创建完后COM对象后,类厂被销毁;
虚方法表(Virtual Method Tables):
接口实现为独立的方法表,该表实现在内存中紧靠VMT的地方;
不同的接口占据不同的内存部分,不能简单的把一个接口值赋给另外一个接口;
通常使用as操作符从一个接口转换为另外一个接口;
2.3 进程外COM服务器(Out-Of-Process COM Server)
目的:理解进程外COM服务器
进程外服务器是在exe中实现; 
实例化(Instancing): 创建多少个客户需要的实例;可以支持三个实例化方法中的一个;
Single Instace(单实例):
只容许一个COM对象的实例
每个需要COM对象实例的应用程序将产生COM服务器的单独拷贝;
Multiple Instance(多实例):
COM Server可以创建一个COM对象的多个拷贝;
客户请求COM对象的一个实例时,由当前运行的服务器创建COM对象的一个实例;
Internal Only(内部实例):用于不被客户应用程序使用的COM对象;
 
调度数据(Marshaling Data):
一个可执行的程序不能直接访问另一个可执行程序的地址空间;
Windows通过调度(Marshaling)进程在调用应用程序和进程外COM服务器之间移动数据;
自动化兼容 SmallInt、Integer、Single、Double、currency、TDateTime、WideString、Idispatch、Scode、WordBool、Olevariant、IUnknown、ShortInt、Byte;
记录和数组不能自动调度;
2.4 Variant 数组
目的:如何使用Variant 数组;
Variant:
一种可以拥有各种数据类型;
也可以告诉目前存储的数据是什么类型(通过使用VarType函数);
可以给相同的Variant分配不同的数据类型,只要Variant包含数字值就可以执行算法;

variant数组只不过是variant型的数组,不必包含同类型的 数据; 
variant数组的创建方法:
function VarArrayCreate(const Bounds: array of Integer; VarType: integer): variant;
Bounds: 告诉数组的上下界;
VarType: 决定了数组的中存储什么类型的数据。

例如:创建数组的数组, 可以模仿任何类型的数据结构类型:
VarArrayX := VarArrayCreate([1,10], varVariant);
数组的单个元素可以装载一个数组: VarArrayX[1] := VarArrayCreate([1,5], varVariant);
function VarArrayOf(const Values: array of Variant): Variant;
运行时用于创建一维数组;
可以创建全异的数值数组;
例如: MyArray := VarArrayOf(['李维', 30, '60', 60.369, 'China']);

使用Variant数组: 与使用标准Delphi数组类似;
VarArrayLowBound、VarArrayHighBound(与数组的low、high类似)计算边界;
VarArrayDimCount:计算数组的维数;
2.5 小结
目的:接口GUID及进程COM服务器的基本知识了解;

Guid是什么;以及为什么Guid对COM是如此重要;如何创建Guid以供自己使用; 
进程内COM服务器,创建及如何使用; 
Variant数组; 是什么、及如何使用; 
进程外COM服务器的介绍、调度及Windows可自动调度的类型; 
只有能理解虚方法表(VMT)的面向对象的语言才能访问只有虚方法表的COM服务器
[第一章 接口][第二章 接口与COM][第三章 类型库][第四章 自动化][第五章 ActiveX][末尾]

第三章 类型库
3.1 定义类型库
目的: 类型库是什么,和它的作用是什么。

使用类型库的好处:
编写自动化控制时早期连接(Early Binding);
许多编译器可以从一种类型库中自动生成针对特定编程语言的代码;
实用程序可以用来读取并显示有关包含类型库的COM服务器的信息;
COM客户和服务器之间自动参数调度;
 
类型库对某些COM服务器是必须的,例如:自动化服务器和ActiveX控件; 
TTypedComObject: Delphi由该类及其派生类提供了对类型库的支持;
Delphi自动创建XXXX_TLB.pas文件;
COM由TTypedComObject派生,而不是TComObjectFactory.Create;
初始时,delphi调用了TTypedComObjectFactory.create、而不是TComObjectFactory.Create;
3.2 使用delphi来创建类型库
目的: 如何使用Delphi来创建类型库的基本知识;

可以使用IDL(Interface Definition LAnguage 接口定义语言)编码类型库; 
类型库编辑器:
工具条:可以添加接口、方法、以及属性到COM服务器中;
注:工具条上可以通过点击鼠标右键弹出的菜单中选择Text Labels命令打开工具条的标题;
Interface(接口): 自动为每一个新建的接口产生一个GUId;
Dispinterface(派遣接口): 与接口类似,但是使用不同的派遣机制调用服务器中的方法;
CoClass(): 类别的定义,被指定给实现接口的COM对象;
使用COM对象之前必须先使用一种方法从类别定义建立真正的类别对象(变量);
再从类别对象取去需要的接口;
最后再从取得的接口中调用需要执行的方法或需要存取的属性;
Enumeration(枚举): 与枚举类型类似;有整数ID来指明,而不是通过集合类型;
Constant(常量):只有在枚举下才有用;可以编辑Name、Value属性;
Alias(别名): 用于定义用户要包括一条记录类型(record)或联合类型(union)中的类型;
Record(记录类型): 记录结构;
Union(联合类型): 等同于Pascal Variant类型;
Module(模块): 模块是方法和常量的集合;
Method(方法): 输入参数(in)、输出参数(out)、可变参数(var);
Property(属性): 只读、只写、读写三种;
Refresh(更新): 使Delphi更新源文件;
Register(注册): 编译COM服务器并把服务器注册到Windows中;
Export(输出到IDL): 在MIDL或Corba格式中很有用;
 
friend
对象列表(Object List):显示服务器中定义的接口、方法等;
页控件(Page control):显示对象列表中当前选中的接点的类型信息;
 
类型库也是一种资源; 
不必在客户应用程序中直接读取类型库;
3.3 小结
目的: 类型库的运用;

类型库是什么; 
如何创建一个类型库; 
如何编译一个类型库类给自己的服务器添加方法、属性及枚举类型; 
如何读取类型库的信息;
[第一章 接口][第二章 接口与COM][第三章 类型库][第四章 自动化][第五章 ActiveX][末尾]

第四章 自动化

通过自动化操作类型库;接口和自动化;Variants和自动化;派遣接口;双重接口;自动化ADO;
4.1 定义自动化
目的: 自动化以及客户通过使用接口、Variants派遣接口和双重接口创建并使用自动化服务器

自动化是一种从应用程序的内部自动控制另一个应用程序的方法。 
获取自动化服务器COM对象的两种主要访问方法:
接口:早期连接(early binding)
早期连接是指对接口方法的所有调用在编译时检查参数是否正确;
Variants: 后期连接 (late binding)
后期连接指连接意味着方法调用直到运行时才被实现;
Variant不是对象指针;对象的调用方法是后期连接;
编写快速、简单的客户应用程序不用费力去输入一个类型库;
 
派遣接口(DispInterface)
在接口和Variant中间的某个地方就是派遣接口;与接口有很多类似;
只是方便客户而设定的;
并没有在服务器上实现派遣接口;是服务器上实现了接口;
假设服务器COM对象也支持IDispatch接口,客户应用程序可以使用Variants或派遣接口;
 
双重接口(Dual Interface): 自动化服务器
简单定义为自动化服务器,支持早期连接(接口)和后期连接(Variants);
使用delphi创建的任何任何自动化服务器将自动支持双重接口;
4.2 进程内自动化服务器
目的: 创建并使用进程内自动化服务器

CreateOleObject和GetActiveOleObject
CreateOleObject:总是创建特定服务器的新实例;
GetActiveOleObject: 用来获取正在内存中运行的服务器的引用;
例如:
       Procedure StartOrLinkToWord;
       var v: Variant;
       begin  
         try
           v := GetActiveOleObject('Word.Basic');  //判断是否Wod已启动;
         except
           v := CreateOleObject('Word.Basic');   //否则启动Word; 通常自动化服务器启动是隐藏的;
           v.AppShow;   //显示Word应用程序;
         end;
         V.FileNew;  //创建一个新的文档;
         v.Insert('Automation is easy!');    
       end;
 
访问自动化服务器的方法:
Interface 通过接口;
Variant 通过Variant: 通过可使用的类名;CreateOleObject
DispInterface 通过派遣接口;
4.3 进程外自动化服务器
目的: 自动化的基础;创建一个Automation服务器,如何使用接口、派遣接口、和Variants来控制此服务器

在本身应作为独立服务器应用程序的情况下,使用进程外非常好; 
HResult:
自动服务器中的所有方法必须返回一个HResult,暗示是成功还是失败;
所有其他参数必须在out参数中返回;
 
safecall:
调用协议可使编码;
指示Delphi自动把所有方法包括在try...except模块中;
在客户端safecall导致客户检查是否有HResult类型的返回失败码;
4.4 COM事件和回调
目的: 两种方式的比较;

派遣接口(DispInterface):
与Interface的比较
DispInterface: 为事件提供了更好的支持;与VB兼容;实现事件是最兼容的方法;
Interface: 不与VB兼容;但速度比派遣接口稍快;
 
回调接口(CallBack Interface):除非有极重要的原因否则不要使用;
服务器做大量的工作,而刻户端不需要太多的工作;
接口中定义回调方法,而不是使用派遣接口把事件送回到客户端;
回调接口在服务器中定义,但在客户中实现;
如果知道服务器和客户提供的接口,回调接口更有效;
4.5 自动化ADO: Microsoft最新的数据库技术;
目的:如何使用Delphi来快速、轻松的使用基于COM的技术;

主要组件:Connection、RecordSet、Command;
Connection对象: 用于连接到一个本地或远处的数据库;
RecordSet对象: 提供了一个记录集的连接;
Command对象: 向数据库发出命令,不返回结果集;
 
连接数据库:Connection.Open();  
记录集打开:RecordSet.Open();  
执行命令:对数据库进行操作,并返回结果集,应使用Command对象(与Parameter一起工作); 
访问字段值:
访问Field对象的值: RecordSet.Fields.Item[FieldNo].Value;
访问字段名称:RecordSet.Fields.Item[FieldNo].Name;
 
数据库错误处理:Error对象,该对象提供任何错误的详细代码;
4.6 小结
目的: 接口、派遣接口和Variants三种方法之间的不同,在特定的环境中使用那种方法;

创建进程内和进程外COM自动化服务器; 
Vraiants在COM自动化服务器中的作用,以及如何使用容许后期连接到自动化对象; 
实现COM事件和回调; 
如何使用Delphi能相对轻松的使用ADO; 
知道接口、派遣接口、和Variants的区别;
[第一章 接口][第二章 接口与COM][第三章 类型库][第四章 自动化][第五章 ActiveX][末尾]

第五章 ActiveX控件和ActiveForms
5.1 ActiveX控件
目的:

 
5.2 创建ActiveX控件;
目的:

 
 
5.3 ActiveForm(Active窗体);
目的: 组件导向的中介软件;ActiveForm的开发;开发浏览器的客户端应用程序;

创建ActiveX工程:
New-->ActiveX-->ActiveX Library
New-->AcitveX-->Active Form
设计时期开发执照;
关于对话框;
版本控制编号;(一般要包括,控制新旧版本、以及是否从服务器下载);
分发:Project-->Web Deploy Options
Target dir: ActiveForm组件于HTML首页中codebase tag的目的;
Target URL: Delphi分发ActiveX组件的时候自动产生一个HTML的首页档案;
HTML dir: 储存这个HTML首页档案的位置;
Use CAB file compression:
Include file version number: 分发时包含版本信息;
Auto increment release number: 自动增加版本编号;
Deploy required package:
Deploy additional file:
project-->Wep deploy开始分发;
5.4 小结
目的:加强ActiveX组件的能力;
使用ActiveX组件; 
如何把已有组件转换为ActiveX组件;实现Delphi没有提供的功能; 
如何从窗体创建ActiveForm;

备注: 有不当的理解之处请大家指正,谢谢;

第六章 DCOM
目的: 客户和服务器端使用DCOM,以及实现远程数据集;
DCOM:分布式COM; 
DCOM服务器COM服务器没有区别,只是位于远程电脑上; 
DCOM服务器的配置: 
DCOM的调用: 必须通过Proxy/Stub对象,并且是通过RPC协议;  
CoClass的CreateRemote方法(Create调用本地);
Proxy: 远程COM对象在应用程序执行中的影象(Image),封装应用程序的调用信息;
Stub:接受Proxy调用信息,再使用这些信息调用真正的DCOM对象;然后调用结果回传给Proxy,由Proxy回传给应用程序;
RPC(Remote Procedure Call): 通信协议,使用DCOM时必须激活;
SCM(Service control Manager):
 
线程模型: 同COM的模型;
组件模型: COM/DCOM组件模型;
COM/DCOM组件模型是一种平台独立、分布式、面向对象的系统,用于创建可相互作用的二进制软件组件。COM/DCOM是微软的OLE(复合文档)和ActiveX(可用于Internet的组件)以及许多其它技术的基础技术;
COM/DCOM之所以被认为是一种二进制标准,是因为它是一种在应用程序被编译成二进制机器码之后才起作用的标准;
COM/DCOM不是一种面向对象语言,它也不指定一个应用程序如何构造,它是一种标准,它指明一种组件模型和使组件之间能够相互操作的编程需求。COM/DCOM组件可以运行在单一进程、不同进程、甚至是远端机器;
COM/DCOM组件可以通过许多编程语言来创建。许多面向对象语言,诸如C++,都提供可简化COM/DCOM组件实现的编程机制;
COM/DCOM定义了一个COM/DCOM组件的核心实质。一般来说,一个软件组件由一组数据以及管理这些数据的函数构成。一个COM/DCOM组件是这样的一种软件组件,它专门通过一组或多组相关的函数存取组件数据。这些函数集合称为接口,而接口的函数称为方法。对COM/DCOM来说,它需要的唯一的调用接口方法的途径就是指向接口的指针;
编译好的COM/DCOM组件是不能修改的,要增加新的功能只能由开发商对组件源码进行修改、更新,然后重新编译生成新的COM/DCOM组件;

[第六章 DCOM][第七章 COM+][第八章 结构化存储]

第七章 COM+
目的: COM+的理解,如何利用系统资源,如何使用COM+,如何开发有效的COM+系统;
MTS(Microsoft Transation Server): 是M$在Windows平台的中介软件之一;  
主要功能:
让Windows程序员开发以组件为导向的分布式应用系统;
具备在同质和异质数据库之间的数据进行Two Phase Commit的功能;
大量的客户端应用程序能够同时执行;
提供数据库事务的管理工作,客户端只要调用中介企业对象的服务、而不需要自行调用StartTranstion等数据库事务模式的程序代码;
MTS本身是一个COM/DCOM对象的Container环境;MTS对象是In-Process COM对象;
提供许多具备延展性的功能:资源pooling、执行pooling、数据库连接pooling、JIT(Just In Time)对象激活等;
MTS组件:本质上是一个COM/DCOM组件;只是MTS组件有一些基本的要求,如下:  
MTS对象必须实现IObjectControl接口;  
MTS对象必须具有Type Library信息;
MTS对象对象必须由标准类别厂商对象建立,即MTS对象必须支持IClassFactory接口;  
MTS对象必须实现IDispatch接口,使用COM标准的marshaling机制;  
简单的说:MTS对象必须支持Automation接口,以便让C++、Pascal以及脚本语言调用;
MTS套件组件: 数个实现MTS对象相关的DLL组合成一个单位,分发时以这个单位为分发的基础;  
函数库套件组件(Library Package):和客户端应用程序一起安装到客户端中;  
服务器套件组件(Service Package):执行在MTS的执行环境中;客户端调用时,要进行远程调用;  
 
CW(Content Wrapper):MTS对象的影像; 可以Object Pooling;节约资源;  
OC(Object Context对象):让MTS对象存取MTS执行环境提供的服务;  
MTS对象和COM/DCOM对象的区别:MTS对象有一个CW对象,提供了前置处理(Pre-process)以及后续处理的工作(Post-Process);  
COM+介绍:  
在Win2000和WinXP中,使用COM+是所有在windows平台中开发应用系统不可回避的事情;
以后的Windows系统中,以COM+作为中介引擎来开发多层应用系统是唯一的选择;  
  
COM+的系统架构:  
程序模型:属性程序模型,组件的执行行为属性由它的执行环境COM+环境来管理;
可以使用MTS Explorer设定的执行属性包括组件的事务属性、组件的安全属性、对象Pooling、平衡负荷、同步处理;
Configured组件和Non-Configured组件:  
Configured组件:安装在服务器应用程序中的COM+组件;有相关的执行行为属性;  
Non-Configured组件:通过注册注册的组件;没有相关的执行行为属性;如ADO组件;  
COM+与MTS环境的区别:COM+主要功能在COM+执行时期函数库和COM+的Stub中;  
COM+没有CW对象:直接调用COM+的实体样例;  
COM+执行在DllHost.Surrogate的应用程序中;  
COM+模型中对象都执行在Context环境中;  
状态对象和无状态对象:  
状态对象: 为客户端维护内部信息使用以下方法:
使用状态对象;
把内部信息写入MTS属性群组中,下次调用时再从属性群组中加载原先储存的信息;
让MTS对象执行完后不要调用SetComplete或SetAbort;
把信息储存在数据库或其他的文件中;
无状态对象:当COM对象服务完客户端后释放所有的内部信息;
事务管理:系统执行企业逻辑程序代码;程序代码的单一的运算必须符合ACID(Atomicity、Consistency、Isolation、durability)标准;
数据库事务管理:  
COM+系统允许程序员使用企业对象在分布式计算环境中对同质与异质数据库中的数据进行Two-Phase Commit的控制;  
只要通过COM+在组件层次提供的事务管理功能,再搭配ADO数据库驱动程序,应用系统能够自动享受COM+执行环境提供的事务管理功能;
程序员不应该在客户端中自己撰写控制数据来源事务的程序代码(StartTranstion等);
Two-Phase Commit:参与数据来源更新的资源保证正确的更新,或在任何参与的资源发生错误时能够完全的恢复数据在未更新之前的状态;  
COM+事务对象:激活数据库事务行为开始的地方;事务对象开始执行后,COM+会建立一个事务Context,调用其他的COM+对象时事务Context会随着流动;事务对象是MTS/COM+中最重要的对象;  
COM+事务的属性而区分的类别:
需要事务:执行时一定需要事务Context的存在;如果已经存在就使用存在的事务Context;
建议:在撰写数据对象、事务对象、协调对象可以使用这种对象;
一般情况下,这种对象是因为要处理数据的修改才会需要一个事务;
需要新的事务:COM+对象在激活时建立一个新的事务Context;而不使用客户端已建立的;
COM+对象在它建立的事务Context中执行,绝对不会在客户端的事务Context中执行;
COM+对象需要建立额外的负荷,COM+的事务不受客户端事务Context控制;
要小心建立这种事务;
支持事务:可以在客户端的事务Context中执行,也可以在没有事务Context的状况下执行;
建议:开发功能对象、控制对象、协调对象时可以选择建立这种对象;
COM+组件是否执行在事务Context中,完全决定于客户端;
不支持事务:不会在COM+的事务Context中执行;
建议:开发COM+对象时尽量不要建立这种对象;
Ignores Transtions:  
MTS/COM+对象的事务属性决定了MTS/COM+是否会进入事务模式以及建立事务Context;  
资源管理: MTS/COM+最主要的功能Two-Phase Commit是依靠资源管理来完成;  
资源管理者(Resource Manager): 管理所有的永续储存媒体的软件组件;  
使永续储存媒体(数据库服务器、信息列、文档系统等)参与MTS/COM+的Two-Phase Commit工作;  
资源分配者(Resource Dispenser):管理所有的非永续储存媒体的软件组件;  
使非永续储存媒体(数据库连接、内存、信息、线程及对象等)参与MTS/COM+的Two-Phase Commit工作;
使非永续储存媒体储存的资源具备Pooling的能力;  
 
MTS/COM+事务生命周期: 事物管理的过程可以分为四个阶段;  
1、激活事务管理:当客户端调用“需要事务”或“需要新的事务”时建立MTS/COM+组件;
2、注册事务管理需要使用的资源管理者: 事务管理中受Two-Phase Commit的保护;
3、执行事务:COM组件执行自己的逻辑代码;
4、事务管理结束:数据的更新、资源的释放;事务管理执行结果是否Commit或RollBack;  
 
MTS/COM+安全机制:

[第六章 DCOM][第七章 COM+][第八章 结构化存储]

第八章 结构化存储
结构化存储与接口一样,是一种技术;
8.1 结构化存储:
目的: 了解什么是结构化存储、和结构化存储文件;

结构化存储文件(DocFiles):提供了一个强大的结构化的保存持续信息的方式; 
结构化存储:单独文件中的一个复杂的文件系统;
结构化存储用语: 目录对应一个存储(storage),文件对应一个流(stream);
8.2 结构化编程:
目的:如何在应用程序中创建、打开、读写结构化存储文件;

创建结构化存储文件:function stgCreateDocFile(...):HResult;stdcall;  
打开结构化存储文件:fucntion stgOpenStorage(...): HREsult; stdcall;  
流(Streams)编程:写文件前要筹建流;  
创建流: IStorage.CreateStream;
打开流: IStorage.OpenStream;
读取流: IStream.Read; Delphi中在读取数据时采用IOleStream;
向流中写数据: IStream.write; Delphi中常常采用TOleStream的类;  
 
创建和使用附加存储(Additional Storages):在存储中创建和访问流;还可以创建子存储;  
创建附加存储: IStorage.CreateStorage;
打开已存在的存储(不是根存储):IStorage.OpenStorage;  
8.3 小结:
目的:结构化存储的使用;

结构化的概念、及如何使用; 
注意: 打开文件和流的少量额外代码,只需使用TOleStream来读写文件;
[第六章 DCOM][第七章 COM+][第八章 结构化存储]

参考书籍:
Delphi5.X ADO/MTS/COM+ 高级程序设计篇
Delphi COM Programming
Effective COM
Inside COM
posted @ 2009-03-30 16:53  谭志宇  阅读(911)  评论(0编辑  收藏  举报