我正在努力用DUnit成功模拟一个Spring4d事件.
事实上,我更嘲笑一个模拟返回模拟事件...
这是基本结构.
TMyObject --EventContainer--> TMock<IEventContainer> --Event--> TMock<IEvent>
Run Code Online (Sandbox Code Playgroud)
TMyObject有一个属性EventContainer:IEventContainer
IEventContainer有一个属性Event:IMyEvent
我想嘲笑
MyObject.EventContainer.Event.Add
Run Code Online (Sandbox Code Playgroud)
我测试了我能想到的每种可能性.我得到AV或无效的演员.我把源代码放在下面.如果有人能帮助我让这个工作真的很漂亮!
program Project2;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils,
DUnitTestRunner,
Spring.Events,
Spring,
Classes,
TestFramework,
Delphi.Mocks;
//Unit1 in 'Unit1.pas';
type
{$M+}
IMyEvent = interface(IEvent<TNotifyEvent>)
procedure Add(const handler: TMethod);
end;
{$M-}
{$M+}
IMyEventMock = interface(IMyEvent)
procedure Add(const handler: TMethod);
end;
{$M-}
{$M+}
IEventContainer = interface(IInterface)
function GetEvent: IMyEvent;
procedure SetEvent(const Value: IMyEvent);
property Event: IMyEvent
read GetEvent
write SetEvent;
end;
{$M-}
{$M+}
ITestEventContainer = interface(IEventContainer)
function GetEvent: TMock<IMyEvent>;
procedure SetEvent(const …Run Code Online (Sandbox Code Playgroud) 我刚刚学习Spring4D,我有一个问题.如果类只实现一个接口,则全部清除:
IWeapon = interface
['{E679EDA6-5D43-44AD-8F96-3B5BD43A147B}']
procedure Attack;
end;
TSword = class(TInterfacedObject, IWeapon)
public
procedure Attack;
end;
GlobalContainer.RegisterType<TSword>.Implements<IWeapon>('sword');
sword := ServiceLocator.GetService<IWeapon>('sword');
Run Code Online (Sandbox Code Playgroud)
我现在很高兴,我有剑,我不需要释放它.
但是如果类实现了两个或更多接口:
IWeapon = interface
['{E679EDA6-5D43-44AD-8F96-3B5BD43A147B}']
procedure Attack;
end;
IShield = interface
['{B2B2F443-85FE-489C-BAF4-538BB5B377B3}']
function Block: Integer;
end;
TSpikedShield = class(TInterfacedObject, IWeapon, IShield)
public
function Block: Integer;
procedure Attack;
end;
GlobalContainer.RegisterType<TSpikedShield>.Implements<IWeapon>.Implements<IShield>;
Run Code Online (Sandbox Code Playgroud)
我可以向ServiceLocator询问TSpikedShield的实例,但我需要选择一个IWeapon或IShield.但我想以两种方式使用它(或者我不应该想要?),如:
spikedShield.Attack;
spikedShield.Block;
Run Code Online (Sandbox Code Playgroud)
所以如果我很好看,我必须直接创建TSpikedShiled的实例(我的意思是没有接口).
function MakeSpikedShield: TSpickedShield;
begin
result := TSpickedShield.Create;
end;
Run Code Online (Sandbox Code Playgroud)
有没有办法使用这个类,但有自动免费?
(如果接口可以实现多次干扰但在delphi中不允许,则不会有问题)
编辑:也许是这样的想法?
ISpikedSield = interface
function AsWeapon: IWeapon;
function AsShield: IShield;
end;
TSpikedShield = class(TInterfacedObject, ISpikedShield)
Run Code Online (Sandbox Code Playgroud) 我有以下代码:
Project.dpr
program Project2;
uses
madExcept,
madLinkDisAsm,
madListHardware,
madListProcesses,
madListModules,
Spring.Container,
Vcl.Forms,
uRegistrations in '..\Memory leak II\uRegistrations.pas',
Unit3 in 'Unit3.pas' {MainForm},
Unit4 in 'Unit4.pas' {SecondaryForm},
Unit5 in 'Unit5.pas';
{$R *.res}
begin
RegisterTypes(GlobalContainer);
Application.Initialize;
Application.MainFormOnTaskbar := True;
// MainForm:=TMainForm.Create(nil);
Application.CreateForm(TMainForm, MainForm);
MainForm.SecondaryForm := Globalcontainer.Resolve<ISecondaryForm>;
Application.Run;
end.
Run Code Online (Sandbox Code Playgroud)
注册接口的uRegistrations.pas
unit uRegistrations;
interface
uses
Spring.Container;
procedure RegisterTypes(Container: TContainer);
implementation
uses
Unit5,
Unit4;
procedure RegisterTypes(Container: TContainer);
begin
container.RegisterType<ISecondaryForm, TSecondaryForm>.DelegateTo(
function: TSecondaryForm
begin
result := TSecondaryForm.Create(nil);
end);
Container.Build;
end;
end.
Run Code Online (Sandbox Code Playgroud)
Unit3.pas持有主表格
unit Unit3;
interface
uses
Winapi.Windows, …Run Code Online (Sandbox Code Playgroud) 我想用Spring4DTDistinctIterator来获得不同Values的TDictionary。因此我有以下代码:
var
d: TDictionary<Integer, String>;
v: Vector<String>;
begin
d := TDictionary<Integer, String>.Create();
d.Add(1, 'test');
d.Add(2, 'test');
d.Add(3, 'test');
v := TDistinctIterator<string>.Create(d.Values, nil).ToArray();
end;
Run Code Online (Sandbox Code Playgroud)
但是,这会导致ToArray. 这是一个错误还是我应该以另一种方式使用迭代器来实现相同的结果?
我试着开始使用spring4d的集合部分.但我不能订阅收集更改事件.得到错误:[DCC错误]:E2008不兼容的类型:
var
TestList: TObjectList<TObject>;
begin
... List initialization code ...
TestList.OnNotify.Add(TestHandler); <--- Error here
end
Run Code Online (Sandbox Code Playgroud)
TObjectList的OnNotify属性声明为:
property OnNotify: ICollectionNotifyDelegate<T>,哪里
ICollectionNotifyDelegate<T> = interface(IMulticastEvent<Generics.Collections.TCollectionNotifyEvent<T>>)
end;
Run Code Online (Sandbox Code Playgroud)
即OnNotify.Add方法需要一个Generics.Collections.TCollectionNotifyEvent,声明为:
TCollectionNotifyEvent<T> = procedure(Sender: TObject; const Item: T;
Action: TCollectionNotification) of object;
Run Code Online (Sandbox Code Playgroud)
我的事件处理程序声明为:
procedure TTestClass.TestHandler(Sender: TObject; const Item: TObject; Action: TCollectionNotification);
begin
end;
Run Code Online (Sandbox Code Playgroud)
我很困惑%)请帮忙)
使用Spring4D的依赖注入框架.
我尝试使用DynamicAbstractFactories.在测试中有2个类和工厂:
IOrderShipper并且IOrderShipperFactory会工作,
IDocument并且IDocumentFactory会失败.
程序TestDocument中的代码将引发
类型不满意的构造函数:DynamicAbstractFactory.TDocument
我不明白为什么......我希望有人知道原因,我觉得真的很蠢
program DynamicAbstractFactory;
{$APPTYPE CONSOLE}
uses
System.Sysutils,
Spring.Container;
type
TEnum = (e1, e2, e3, e4, e5);
IDocument = interface
['{CCB718EF-7670-4157-97FF-0E49ACBEB449}']
procedure Show;
end;
IDocumentFactory = interface(IInvokable)
['{73ADE7C1-3119-45B6-B615-04A4079AA581}']
function Create: IDocument; overload;
function Create(ID: integer; DocType: TEnum; Level: integer): IDocument; overload;
end;
IOrderShipper = interface
['{F4653C0C-2C05-4348-A744-3288E520F586}']
procedure Ship;
end;
IOrderShipperFactory = interface(IInvokable)
['{F632D1FB-9C34-48FD-BD72-6BBC436D1B47}']
function Create: IOrderShipper; overload;
function Create(const name: string): IOrderShipper; overload;
function Create(aId: integer; en: TEnum; Level: …Run Code Online (Sandbox Code Playgroud) spring4d中基于接口的集合如何处理其元素的生命周期?我想要实现的是当集合超出范围时,包含的对象也被释放,并且它们的析构函数被调用.目前还不确定是这种情况.