标签: spring4d

Spring for Delphi中GlobalContainer和ServiceLocator有什么区别?

他们看起来很相似.我可以在GlobalContainer中注册一些东西:

GlobalContainer.RegisterType<TMyImplementation>.Implements<IMyInterface>;
Run Code Online (Sandbox Code Playgroud)

并通过GlobalContainer或获取实例ServiceLocator,它们都工作:

MyInstance := GlobalContainer.Resolve<IMyInterface>;
MyInstance := ServiceLocator.GetService<IMyInterface>;
Run Code Online (Sandbox Code Playgroud)

delphi spring4d

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

spring4d 注销接口类型(spring4d、dunitx、delphi-mocks)

我正在使用 spring4d、dunitx 和 delphi-mocks 编写我的第一个单元测试。(spring4d 版本 1.1 - 2014 年 9 月 12 日)

在我的测试应用程序中,我将一个接口自动连接到我的被测系统类 (sut):

IMyInterface = interface [{yes, a GUID here}]
  function GetSomething1: TSomething1;
  function GetSomething2: TSomething2;
end;

TMyClass = class
private
    [Inject]
    FMyInterface: IMyInterface;
    // ...
end;
Run Code Online (Sandbox Code Playgroud)

现在,当我使用带有模拟的单元测试时,我使用以下(非常简单的)代码:

TMyTest = class
private
    [Test]
    procedure Test1;

    [Test]
    procedure Test2;
    // ...
end;

procedure TMyTest.Test1;
var
    aSut: TMyClass;
    aIntfMock: TMock<IMyInterface>;
    aSomething1: TSomething1;
begin
    // Arrange
    GlobalContainer.RegisterType<TMyClass>;

    aIntfMock := TMock<IMyInterface>.Create;
    try
        GlobalContainer.RegisterType<IMyInterface>.DelegateTo(
            function: IMyInterface
            begin
                Result := aIntfMock;
            end)
            .AsDefault; …
Run Code Online (Sandbox Code Playgroud)

delphi unit-testing spring4d delphi-mocks

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

有地图功能吗?

我刚写了这个函数:

class function TGenerics.Map<TFrom, TTo>(const AEnumerable: IEnumerable<TFrom>;
  const AConverter: TConstFunc<TFrom, TTo>): IList<TTo>;
var
  L: IList<TTo>;
begin
  L := TCollections.CreateList<TTo>;
  AEnumerable.ForEach(
    procedure(const AItem: TFrom)
    begin
      L.Add(AConverter(AItem));
    end
  );
  Result := L;
end;
Run Code Online (Sandbox Code Playgroud)

这大致相当于Haskells map(或fmap,liftM等).

所以我想知道Spring4D中是否存在类似的东西?

delphi collections delphi-xe2 spring4d

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

Delphi Spring4D IList内存溢出

我正在使用来自Stefan Glienke的优秀Delphi框架Spring4D的IList.

我有一个列表IList,我在我的应用程序运行期间多次重新填充此列表.所以,经过两三个小时后,我的列表中有内存溢出.

这就是我填充列表的方式:

  list := TCollections.CreateList<TVisitor>;

  for i := 0 to dataSet.RecordCount - 1 do begin
        item := TVisitor.Create ();

        item.Surname := dataSet.FieldByName ( 'firstname' ).AsString;
        item.Name := dataSet.FieldByName ( 'secondname' ).AsString;
        item.Patronymic := dataSet.FieldByName ( 'thirdname' ).AsString;
        item.CardNumber := dataSet.FieldByName ( 'cardnumber' ).AsString;

        list.Add ( item );

        dataSet.Next ();
  end;
Run Code Online (Sandbox Code Playgroud)

Clear()方法不释放内存,所以每次我填写我的列表Windows任务管理器inc我的应用程序的内存使用情况:(

memory delphi list overflow spring4d

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

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
查看次数

Spring 框架中是否有内置的方法可以使多态容器的使用变得更容易?

我有一个包含不同类型值的字典,我想过滤具有特定子类型且满足特定条件的项目:

var
  FData: IDictionary<TGUID, TObject>; // Polymorphic
begin
  TMicroStep(FData.Values.Single(
    function(const O: TObject): Boolean begin
      Result := (O is TMicroStep) and (TMicroStep(O).OrderTag = 1);
  end))
end;
Run Code Online (Sandbox Code Playgroud)

它可以工作,但由于类型检查和双重强制转换,它看起来很难看。

也许这样的事情是可能的?

var
  FData: IDictionary<TGUID, TObject>; // Polymorphic
begin
  FData.Values.SingleSubType<TMicroStep>(
    function(const MS: TMicroStep): Boolean begin
      Result := MS.OrderTag = 1;
  end))
end;
Run Code Online (Sandbox Code Playgroud)

Spring 有什么可以帮助我的吗?

delphi polymorphism containers delphi-xe2 spring4d

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

Delphi,如何避免application.CreateForm?

我使用Spring4d框架 进行依赖注入和其他事情.

在应用程序入口点,我必须创建应用程序"Main"表单.虽然,我不知道其他任何方式

Application.CreateForm(TMainForm, MainForm) 
Run Code Online (Sandbox Code Playgroud)

创造这个.

是否可以使用Spring4d依赖注入创建Main表单?像这样:

MainForm := GlobalContainer.Resolve<IMainForm>;
Run Code Online (Sandbox Code Playgroud)

然后将其设置为打开应用程序时显示的表单?

delphi dependency-injection spring4d

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

Spring4d:Spring.Collections.IEnumerator和System.IEnumerator

我有一个问题应该是微不足道的,但我找不到任何优雅的答案.

我有一个a的实例,IList<string>我想得到一个逗号分隔的字符串,其中包含所有不同的(不区分大小写)值.

我以为我只是使用string.Join帮助器,因为它有一个很好的重载接受一个IEnumerator<string>as参数.不幸的是,我看到了一个障碍:spring4d重新定义IEnumerator<T>,当然,到处都使用自己的类型.

结果是以下代码无法编译:

var
  distinct: system.IEnumerator<string>;
begin
  result := inherited GetToken;
  if assigned(result) then
  begin
    if not Modules.Contains(STR_DID_SESSION_MODULE) then
      Modules.Add(STR_DID_SESSION_MODULE); 
    distinct := TDistinctIterator<string>.Create(Modules, TIStringComparer.Ordinal);
    result.CustomClaims.Items[STR_CLAIM_CUSTOM_MODULES] := string.Join(',', distinct);
  end;
end;
Run Code Online (Sandbox Code Playgroud)

分配distinct失败E2010 Incompatible types: 'System.IEnumerator<System.string>' and 'Spring.Collections.Extensions.TDistinctIterator<System.string>'

或者,如果我从distinct中删除命名空间,那么对它的调用将string.Join失败.

知道我应该怎么做吗?没有手动遍历迭代并手动执行连接?

delphi spring4d delphi-10.2-tokyo

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

Delphi SysUtils.Supports意外返回true

我正在根据Spring4d的文档示例制作一个eventPublisher

不同之处在于订阅者必须明确订阅事件.

我想触发他们的Handle程序基于是否实现IEventHandler<TEventType>接口.

发布传入事件时,我IEventHandler<TEventType>使用事件的类名和Spring4d 找到类型引用TType.FindType('IEventHandler<TEvent1>')

然后我遍历我的订阅者(实现IEventHandler接口的对象)并检查它是否支持IEventHandler类型.

问题是即使订户没有实现接口,Supports方法也会返回true.

此外,我尝试列出说TMyEventHandler2类型的接口.它包含IEventHandler<TEvent2>??

我相信这是由于IEventHandler<TEvent2>IEventHandler<TEvent1>共享相同的GUID 的限制

这有解决方法吗?

使用这些类和接口:

TEvent1 = class(TObject)
end;

TEvent2 = class(TObject)
end;

IEventHandler = interface(IInvokable)
[guid]
procedure Handle(aEvent : TObject);
end;

IEventHandler<T : class> = interface(IEventHandler)
[guid]
procedure Handle(aEvent : T);
end;

TMyEventHandler1 = class(TObject, IEventHandler, IEventHandler<TEvent1>)
public 
procedure Handle(AEvent : TObject); overload;
procedure Handle(AEvent : TEvent1); overload;
end;

TMyEventHandler2 = class(TObject, IEventHandler, IEventHandler<TEvent2>)
public 
procedure Handle(AEvent : TObject); …
Run Code Online (Sandbox Code Playgroud)

delphi reflection interface rtti spring4d

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