小编Ric*_*ler的帖子

父属性的构造函数注入与setter注入

我正在试图找出对一些遗留代码使用依赖注入的最佳方法,这将需要很长时间才能重构并且必须逐步完成.大多数旧类使用"Parent"属性来确定各种事物,而父属性通常通过构造函数参数传递,如下所示:

constructor TParentObject.Create;
begin
  FChildObject := TChildObject.Create(Self);
end;

constructor TChildObject.Create(AParent: TParentObject)
begin
  FParent := AParent;
end;
Run Code Online (Sandbox Code Playgroud)

这是我们遗留代码库的典型代表.但是,当移动到接口和构造函数注入时,Spring4D框架在创建Child对象时不知道Parent.所以它只会得到一个新的父母而不是现有的父母.当然我可以创建一个属性getter/setter,但这表示该类的"可选"属性,它实际上是一个强制属性.有关更多说明,请参阅以下代码:

unit uInterfaces;

interface

uses
  Spring.Collections;

type

  IChildObject = interface;

  IParentObject = interface
  ['{8EA8F9A2-E627-4546-8008-0A77DA2B16F1}']
    function GetSomethingRequiredByChild: string;
    procedure SetSomethingRequiredByChild(const Value: string);
    property SomethingRequiredByChild: string read GetSomethingRequiredByChild write SetSomethingRequiredByChild;
    function GetChild: IChildObject;
    property Child: IChildObject read GetChild;
  end;

  // This introduces a property getter/setter
  // However it also implies that Parent can be NIL which it cannot
  IChildObject = interface
  ['{ECCA09A6-4A52-4BE4-A72E-2801160A9086}']
    function GetParent: IParentObject;
    procedure …
Run Code Online (Sandbox Code Playgroud)

delphi dependency-injection spring4d

13
推荐指数
1
解决办法
804
查看次数

使用FreeOnTerminate = True的TThread的Delphi单元测试

当FreeOnTerminate = True时,为TThread后代编写Delphi DUnit测试的最佳方法是什么?TThread后代返回一个我需要测试的引用,但我无法弄清楚如何等待线程在测试中完成...

unit uThreadTests;

interface

uses
  Classes, TestFramework;

type

  TMyThread = class(TThread)
  strict private
    FId: Integer;
  protected
    procedure Execute; override;
  public
    constructor Create(AId: Integer);
    property Id: Integer read FId;
  end;

  TestTMyThread = class(TTestCase)
  strict private
    FMyId: Integer;
    procedure OnThreadTerminate(Sender: TObject);
  protected
    procedure SetUp; override;
    procedure TearDown; override;
  published
    procedure TestMyThread;
  end;

implementation

{ TMyThread }

constructor TMyThread.Create(AId: Integer);
begin
  FreeOnTerminate := True;
  FId := AId;

  inherited Create(False);
end;

procedure TMyThread.Execute;
begin
  inherited;

  FId := FId + 1;
end; …
Run Code Online (Sandbox Code Playgroud)

delphi unit-testing dunit tthread delphi-2010

12
推荐指数
1
解决办法
4500
查看次数

Delphi界面助手/解决方法

我意识到Delphi不支持接口助手,但在阅读了几个SO主题和Spring4D的来源之后,我想知道有没有办法实现以下目的?源代码评论几乎总结了我正在尝试做的事情,所以这里是:

program IHelper;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  Spring,
  System.SysUtils;

type

  IMyThing = interface
  ['{01E799A5-9141-4C5E-AA85-B7C9792024D9}']
    procedure BasicThing;
  end;

  TMyThing = class(TInterfacedObject, IMyThing)
  strict private
    procedure BasicThing;
  end;

  IMyThingHelper = record
  private
    FOutage: IMyThing;
  public
    class operator Implicit(const Value: IMyThing): IMyThingHelper;
    procedure HelpfulThing;
  end;

  TMyThingHelper = class helper for TMyThing
  public
    class procedure ObjectThing;
  end;

{ TOutage }

procedure TMyThing.BasicThing;
begin
  Writeln('Basic Thing');
end;


{ IOutageHelper }

procedure IMyThingHelper.HelpfulThing;
begin
  Writeln('Helpful thing');
end;

class operator IMyThingHelper.Implicit(const Value: IMyThing): IMyThingHelper;
begin
  Result.FOutage …
Run Code Online (Sandbox Code Playgroud)

delphi interface spring4d delphi-xe5

10
推荐指数
1
解决办法
2215
查看次数

在Delphi 2010中从XML读取°度符号

无法从Delphi读取以下XML ,因为它包含无效的°符号:

V1:   <Item Id="1" Description="90° Hinge"/>
Run Code Online (Sandbox Code Playgroud)

似乎Delphi 承认在XML中执行此操作的"标准"方式:

V2:   <Item Id="1" Description="90&deg; Hinge"/>
Run Code Online (Sandbox Code Playgroud)

德尔福似乎确实处理了这个问题:

V3:   <Item Id="1" Description="90&#176; Hinge"/>
Run Code Online (Sandbox Code Playgroud)

由于我从RESTful Web服务获取数据,因此我无法控制所遇到的XML数据包,我只需要能够读取它们.

问题

  1. 如果V2是标准的XML方式,那为什么Delphi不支持这个呢?还是有一种特殊的方式来处理这个我不知道的事情?
  2. V1 XML是否刚开始形成?如果是这样,我应该请求将RESTful接口更改为以V3格式导出°.

使用Delphi 2010.任何帮助将不胜感激.

xml delphi delphi-2010

8
推荐指数
3
解决办法
1755
查看次数

为什么Delphi允许构造函数参数不正确?

这似乎是一个非常愚蠢的问题,但我不知道为什么甚至允许编译:

program ConstructorWithParam;

{$APPTYPE CONSOLE}

uses
  System.SysUtils;

type

  TThing = class(TObject)
  private
    FParent: TObject;
  public
    constructor Create(const AParent: TObject);
  end;

{ TThing }

constructor TThing.Create; // <- WTF? Why does the compiler not complain?
begin
  FParent := AParent;
end;

var
  Thing: TThing;
begin
  try
    Thing := TThing.Create(TObject.Create);
    Readln;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.
Run Code Online (Sandbox Code Playgroud)

我正在使用Delphi XE5并且没有在其他版本上测试过.谢谢.

delphi

6
推荐指数
1
解决办法
155
查看次数

具有接口类型约束的泛型类型的RTTI

是否可以检查具有接口类型约束的泛型类型实例的RTTI信息?问题可能有点模糊,所以我创建了一个示例控制台应用程序来显示我正在尝试做的事情:

program Project3;

{$APPTYPE CONSOLE}

uses
  RTTI,
  SysUtils,
  TypInfo;

type
  TMyAttribute = class(TCustomAttribute)
  strict private
    FName: string;
  public
    constructor Create(AName: string);
    property Name: string read FName;
  end;

  IMyObjectBase = interface
  ['{E063AD44-B7F1-443C-B9FE-AEB7395B39DE}']
    procedure DoSomething;
  end;

  TMyObjectBase = class(TInterfacedObject, IMyObjectBase)
  public
    procedure DoSomething; virtual;
  end;

  [TMyAttribute('First')]
  TMyFirstRealClass = class(TMyObjectBase)
  public
    procedure DoSomethingDifferent;
  end;

  [TMyAttribute('Second')]
  TMySecondRealClass = class(TMyObjectBase)
  public
    procedure BeSomethingDifferent;
  end;

  TGenericClass<I: IMyObjectBase> = class
  public
    function GetAttributeName(AObject: I): string;
  end;


{ TMyAttribute }

constructor TMyAttribute.Create(AName: string);
begin
  FName := AName;
end; …
Run Code Online (Sandbox Code Playgroud)

delphi generics interface rtti

5
推荐指数
1
解决办法
926
查看次数

Delphi泛型TObjectList <T>继承

我想创建一个TObjectList<T>后代来处理我的应用程序中的对象列表之间的常见功能.然后我想进一步从新类继续下载,以便在需要时引入其他功能.我似乎无法使用超过1级的继承.我可能需要更多地了解泛型,但是我搜索高低都是正确的方法来做到这一点而没有成功.到目前为止,这是我的代码:

unit edGenerics;

interface

uses
  Generics.Collections;

type

  TObjectBase = class
  public
    procedure SomeBaseFunction;
  end;

  TObjectBaseList<T: TObjectBase> = class(TObjectList<T>)
  public
    procedure SomeOtherBaseFunction;
  end;

  TIndexedObject = class(TObjectBase)
  protected
    FIndex: Integer;
  public
    property Index: Integer read FIndex write FIndex;
  end;

  TIndexedObjectList<T: TIndexedObject> = class(TObjectBaseList<T>)
  private
    function GetNextAutoIndex: Integer;
  public
    function Add(AObject: T): Integer;
    function ItemByIndex(AIndex: Integer): T;
    procedure Insert(AIndex: Integer; AObject: T);
  end;

  TCatalogueItem = class(TIndexedObject)
  private
    FID: integer;
  public
    property ID: integer read FId write FId;
  end;

  TCatalogueItemList = class(TIndexedObjectList<TCatalogueItem>) …
Run Code Online (Sandbox Code Playgroud)

delphi generics delphi-2010

4
推荐指数
1
解决办法
6677
查看次数

Delphi Spring框架注册泛型类型

使用Delphi Spring框架,是否可以使用GlobalContainter注册泛型类型?我正在尝试做这样的事情:

TMyBaseType = class
protected
  FName: string;
  function GetName: string; virtual;
  procedure SetName(Value: string); virtual;
public
  property Name: string read GetName write SetName;
end;

TMyFirstThing = class(TMyBaseType)
protected
  function GetName: string; override;
end;

TMySecondThing = class(TMyBaseType)
protected
  procedure SetName(Value: string); override;
end;

TMyGenericType<T: TMyBaseType> = class
public
  procedure DoSomethingWithIt(AObject: T);
  function GetTheSomethingsName(AObject: T): string;
end;

// I now want to be able to use the ServiceLocator to get me an instance
// such as TMyGenericType<TMyFirstThing> or TMyGenericType<TMySecondThing>
// but …
Run Code Online (Sandbox Code Playgroud)

delphi generics delphi-2010 spring4d

4
推荐指数
1
解决办法
743
查看次数

Delphi 接口和 IList&lt;T&gt;(或 TObjectList&lt;T&gt;)

我正在尝试实现 Spring 4 Delphi,并且只对接口而不是类进行编程。然而,当您想使用 TObjectList 时,这似乎是不可能的。

考虑以下代码:

unit Unit1;

interface

uses
  Spring.Collections,
  Spring.Collections.Lists;

type

  IMyObjParent = interface
  ['{E063AD44-B7F1-443C-B9FE-AEB7395B39DE}']
    procedure ParentDoSomething;
  end;

  IMyObjChild = interface(IMyObjParent)
  ['{E063AD44-B7F1-443C-B9FE-AEB7395B39DE}']
    procedure ChildDoSomething;
  end;

implementation

type
  TMyObjChild = class(TInterfacedObject, IMyObjChild)
  protected
    procedure ParentDoSomething;
  public
    procedure ChildDoSomething;
  end;


{ TMyObj }

procedure TMyObjChild.ChildDoSomething;
begin

end;

procedure TMyObjChild.ParentDoSomething;
begin

end;

procedure TestIt;
var
  LMyList: IList<IMyObjChild>;
begin
  TCollections.CreateObjectList<IMyObjChild>;
  //[DCC Error] Unit1.pas(53): E2511 Type parameter 'T' must be a class type
end;

end.
Run Code Online (Sandbox Code Playgroud)

我知道我可以在上面的示例中将 IMyObjChild 更改为 TMyObjChild,但如果我在另一个单元或表单中需要它,那么我该怎么做?

当您需要 TObjectList 时,尝试仅对接口进行编程似乎太困难或不可能。 …

delphi generics spring4d

4
推荐指数
1
解决办法
6081
查看次数

用于通用记录的Delphi TypeInfo

我正在尝试使用RTTI的通用记录,但遇到类型信息的问题.有谁知道为什么以下不能使用Delphi 2010进行编译?

program GenericTypeInfo;

{$APPTYPE CONSOLE}

uses
  TypInfo,
  SysUtils;

type

  TMyRec<T> = record
  public
    Value: T;
  end;

  TMyInt = TMyRec<Integer>;
  TMyString = TMyRec<String>;

begin

  try
    Writeln(GetTypeName(TypeInfo(TMyRec<Integer>)));     <--- This works fine
    Writeln(GetTypeName(TypeInfo(TMyRec<String>)));      <---   so does this
    Writeln(GetTypeName(TypeInfo(TMyInt)));              <--- BUT this won't compile
    Writeln(GetTypeName(TypeInfo(TMyString)));           <---   nor this!!
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;

  Readln;

end.
Run Code Online (Sandbox Code Playgroud)

上面指出的行会生成以下编译器错误:

[DCC Error] GenericTypeInfo.dpr(24): E2134 Type 'TMyInt' has no type info
[DCC Error] GenericTypeInfo.dpr(24): E2134 Type 'TMyString' has no type info
Run Code Online (Sandbox Code Playgroud)

我不能说2之间的最大区别是什么?我承认我不是一个低级别的专家,但为什么编译器会以不同的方式对待它?我需要它来为TMyInt和TMyString类型工作.

谢谢你的帮助.

delphi generics rtti typeinfo delphi-2010

3
推荐指数
1
解决办法
3229
查看次数

Delphi使用可空类型进行模拟

使用Spring框架中的Nullable类型设置Delphi DSharp模拟的最佳方法是什么?我尝试了各种方法,我知道我可能遗漏了一些非常简陋的东西,但我无法弄清楚如何让以下代码工作:

program DSharkMockNullable;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  DSharp.Testing.Mock,
  Spring,
  System.SysUtils;

type

  {$M+}
  IBaseMock = interface
  ['{B3311345-3C1F-47E3-8235-57B1BA04E957}']
    function GetId:  TNullableInteger;
    procedure SetId(Value: TNullableInteger);
    property Id: TNullableInteger read GetId write SetId;
  end;

  {$M+}
  IMockMe = interface(IBaseMock)
  ['{07F8F233-E8F5-4743-88C5-97A66BB01E29}']
    function GetObjectId:  TNullableInteger;
    procedure SetObjectId(Value: TNullableInteger);
    property ObjectId: TNullableInteger read GetObjectId write SetObjectId;
    function GetObjectName:  TNullableString;
    procedure SetObjectName(Value: TNullableString);
    property ObjectName: TNullableString read GetObjectName write SetObjectName;
  end;

  TMyObject = class
  public
    function ObjectIdAsString(const AObject: IMockMe): string;
  end;


{ TMyObject }

function TMyObject.ObjectIdAsString(const AObject: …
Run Code Online (Sandbox Code Playgroud)

delphi mocking spring4d

3
推荐指数
1
解决办法
632
查看次数

无法获得Spring4D加密示例的预期结果

Spring4D库有加密类,但我无法按预期工作.我可能错误地使用它们,但是缺少任何示例都会让它变得困难.

例如,在网站https://quickhash.com/hash-sha256-online上,我可以散列单词"test"来生成以下哈希:

9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08
Run Code Online (Sandbox Code Playgroud)

使用Spring4D库,以下代码生成不同的哈希:

CreateSHA256.ComputeHash('test').ToString;
Run Code Online (Sandbox Code Playgroud)

结果是:

9EFEA1AEAC9EDA04A892885A65FDAE0E6D9BE8C9FC96DA76D31B929262E12B1D
Run Code Online (Sandbox Code Playgroud)

抛开大/小写,它完全是一个不同的哈希.我知道一定是做错了,但是再没有使用的例子,所以我一直坚持如何做到这一点.

delphi hash cryptography spring4d

3
推荐指数
1
解决办法
364
查看次数