他们看起来很相似.我可以在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) 我正在使用 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) 我刚写了这个函数:
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中是否存在类似的东西?
我正在使用来自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我的应用程序的内存使用情况:(
使用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) 我正在尝试实现 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 时,尝试仅对接口进行编程似乎太困难或不可能。 …
我有一个包含不同类型值的字典,我想过滤具有特定子类型且满足特定条件的项目:
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 有什么可以帮助我的吗?
我使用Spring4d框架 进行依赖注入和其他事情.
在应用程序入口点,我必须创建应用程序"Main"表单.虽然,我不知道其他任何方式
Application.CreateForm(TMainForm, MainForm)
Run Code Online (Sandbox Code Playgroud)
创造这个.
是否可以使用Spring4d依赖注入创建Main表单?像这样:
MainForm := GlobalContainer.Resolve<IMainForm>;
Run Code Online (Sandbox Code Playgroud)
然后将其设置为打开应用程序时显示的表单?
我有一个问题应该是微不足道的,但我找不到任何优雅的答案.
我有一个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失败.
知道我应该怎么做吗?没有手动遍历迭代并手动执行连接?
我正在根据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 ×10
spring4d ×10
delphi-xe2 ×2
generics ×2
collections ×1
containers ×1
delphi-2010 ×1
delphi-mocks ×1
interface ×1
list ×1
memory ×1
overflow ×1
polymorphism ×1
reflection ×1
rtti ×1
unit-testing ×1