【发布时间】:2018-12-30 17:52:21
【问题描述】:
我使用 Bold for Delphi 作为 ORM 框架,并尝试编写代码生成如何工作以更好地理解我的问题。存储在 bld 文件中的模型用作为模型中的类生成类定义的源。
所以从头开始生成一个名为 BusinessClasses.pas 的文件。 结构是这样的:
unit BusinessClasses;
{$DEFINE BusinessClasses_unitheader}
{$INCLUDE BusinessClasses_Interface.inc}
{$INCLUDE AmObject.inc}
{$INCLUDE Quantity.inc}
{$INCLUDE Distance.inc}
// etc. My source have about 80 inc-files with code
const
BoldMemberAssertInvalidObjectType: string = 'Object of singlelink (%s.%s) is of wrong type (is %s, should be %s)';
{ TBusinessClassesRoot
All classes in model inherit from TBusinessClassesRoot.
Following is base methods that can be used everywhere}
procedure TBusinessClassesRootList.Add(NewObject: TBusinessClassesRoot);
begin
if Assigned(NewObject) then
AddElement(NewObject);
end;
function TBusinessClassesRootList.IndexOf(anObject: TBusinessClassesRoot): Integer;
begin
result := IndexOfElement(anObject);
end;
function TVehicle._GetRegNo: String;
begin
Result := M_RegNo.AsString;
end;
procedure TVehicle._SetRegNo(const NewValue: String);
begin
M_RegNo.AsString := NewValue;
end;
// So all basic methods that Get and Set attributes for all classes is here.
// In my case it means a big file about 83000 LOC.
BusinessClasses_Interface.inc 中的代码如下所示:
{$IFNDEF BusinessClasses_Interface.inc}
{$DEFINE BusinessClasses_Interface.inc}
{$IFNDEF BusinessClasses_unitheader}
unit BusinessClasses;
{$ENDIF}
interface
uses
// interface uses
{$INCLUDE Attracs_Interface_Uses.inc} ,
// other
Classes,
// more uses follow...
type
{ forward declarations of all classes }
TBusinessClassesRoot = class;
TBusinessClassesRootList = class;
TaccountProperty_TransportAccountProperty = class;
TaccountProperty_TransportAccountPropertyList = class;
// A lot of forward declarations follow....
TBusinessClassesRoot = class(TBoldObject)
private
protected
public
end;
TaccountProperty_TransportAccountProperty = class(TBusinessClassesRoot)
private
function _GetaccountProperty: TTransportAccountProperty;
function _Get_M_accountProperty: TBoldObjectReference;
protected
public
property M_accountProperty: TBoldObjectReference read _Get_M_accountProperty;
property accountProperty: TTransportAccountProperty read _GetaccountProperty;
end;
// More class declarations follow
// File size is about 35000 LOC
所以 BusinessClasses_Interface.inc 和 BusinessClasses.pas 是从头开始生成的 而像 AmObject.inc 这样的带有真实代码的 inc 文件则由开发人员维护。
从 D7 开始就一直这样工作。但也有一些缺点。
- Codeinsight 在 inc 文件中无法正常工作
- 许多分析 Delphi 代码的工具不适用于 inc 文件
- 由于某些原因,有时项目无法编译,因为 BusinessClasses_Interface.inc 被 bds.exe 锁定。 有时重启是唯一的选择,但它是随机的。
所以我最初的想法是将所有 inc 文件转换为标准的 pas 文件。对代码的引用应该通过 uses 而不是 $INCLUDE inc-file。然后我发现为什么选择了这种将代码存储在 inc 文件中的奇怪解决方案。模型中的两个类可以相互关联。这意味着A类引用了B类。B类引用了A类。这必须有效。类前向声明用于此。 Delphi 编译器似乎需要这个。
前向声明必须由同一类型声明部分中同一类的定义声明来解析。换句话说,在前向声明和它的定义声明之间,除了其他类型声明之外,什么都不会发生。
所以 Delphi 10.3 Rio 的工作方式与旧 D7 完全相同。
好的,现在我的问题终于来了:)
除了 Bold 之外,我还没有看到任何其他项目使用 inc 文件来存储代码。 是否有任何其他技巧或解决方案可以达到相同的结果?
【问题讨论】:
-
FPC 使用 .inc 文件。 yunqa 的整个产品线(DIContainers、DISQLite3 等)也是如此。
-
但是这些项目是否使用 inc 文件作为代码?我只看到它被用于常量和 $DEFINE。