配件是.NET 应 用
程序和库的离散部署模块,其中包含了.NET 的中间语言(IL)代码。配件可以是可执行 模块(.exe 文件)或者是共享的库(.dll 文件) 。这里调用配件的客户程序既可以是另一个配 件(如 Gardener 配件调用 Fruit 配件) ,也可以是主程序(如调用 Gardener 配件的 Program
主程序) 。但对于客户程序是用何种语言开发的并没有指定,只要是.NET 兼容的语言既可。 本文最后会用 J#程序来调用配件,演示果园系统的运行效果。
Fruit uses clas s e s TFruit TBerry TCitrusFruit TTropicalFruit
Garde ne r clas s e s TGardener
uses Program
图 3 果园系统的实现图
接下来,我们的 Delphi 程序员先用 Delphi 2005 来创建一个 Fruit 配件(fruitLib.dll) 。 在 Delphi 2005 集成开发环境(IDE)中点击工具栏上的 New Items 按钮,弹出如图 4 所示 的 New Items 对话框。在对话框左边选择 Delphi for .NET Projects 类别,右边选择 Package 项目,系统会自动创建一个 Package 项目,如图 5 左图所示。
图 4 通过 Delphi2005 的 Package 向导创建 Fruit 配件(fruitLib.dll)
注意,New Items 对话框中的 Package 和 Library 比较容易搞混淆。这里的 Package 已经 不是传统 Delphi 中包的概念了,而是完全匹配.NET 的配件,相当于 C#中的 Class Library。 这里的 Library 反而是用于创建与 Win32 兼容的配件,不像 Package 配件那样将其所包含单
元中的所有代码都链接
进来。 一旦创建好 Package 项目,就可以向其添加代码单元文件。鼠标右键点击 Package1 项 目的 Contains 文件夹,选择弹出菜单的 Add…菜单项,打开 Add 对话框,如图 5 右图所示 添加一个已有的单元。或者也可以直接在 Contains 文件夹中新建一个 Delphi 单元文件。
图 5 向 Package 中添加 Delphi 的 Fruit 单元文件 我们将这个在 Package 项目命名为 fruitLib。 现在我们在 fruitLib 项目的 Fruit 单元中撰 写 TFruit 和 TBerry、TTropicalFruit、TCitrusFruit 几个类,其代码如示例程序 1 所示。 TBerry、 TTropicalFruit、 TCitrusFruit 都是 TFruit 的派生类, 它们继承了 TFruit 类的 create、 grow、harvest、gain 方法。但是,因为不同派生类对投资收益有不同的计算方法,所以分别 覆盖了基类的 gain 方法,从而在后面的计算中可以实现多态。 调试无误后,我们就可以编译得到 fruitLib.dll 文件,这就是一个标准的.NET 配件。 示例程序 1 Fruit 单元的源代码
1: unit Fruit; 2: 3: interface 4: 5: type 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: TBerry = class (TFruit) public TFruit = class (TObject) protected FFruitName: string; FInput: Integer; public constructor create(name:string;investment:integer); function gain: Integer; virtual; procedure grow; procedure harvest; end;
19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31:
function gain: Integer; override; end;
TCitrusFruit = class (TFruit) public function gain: Integer; override; end;
TTropicalFruit = class (TFruit) public function gain: Integer; override; end;
32: implementation 33: 34: { TFruit } 35: constructor TFruit.create(name:string;investment:integer); 36: begin 37: 38: 39: inherited create; FFruitName:=name; FInput:= investment;
40: end; 41: 42: function TFruit.gain: Integer; 43: begin 44: result:=FInput*2;
45: end; 46: 47: procedure TFruit.grow; 48: begin 49: writeln(FFruitName+'生长……');
50: end; 51: 52: procedure TFruit.harvest; 53: begin 54: writeln(FFruitName+'收获……');
55: end; 56: 57: { TBerry } 58: function TBerry.gain: Integer; 59: var 60: g: Integer;
61: begin 62: if FInput>20 then
63: 64: 65: 66: 67:
g:=inherited gain -200 els