标签: spring4d

如何用DUnit模拟Spring4D事件

我正在努力用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)

delphi unit-testing dunit spring4d

2
推荐指数
1
解决办法
352
查看次数

如何在Spring4D中使用多接口类

我刚刚学习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)

delphi interface spring4d

2
推荐指数
1
解决办法
261
查看次数

Spring4D中的TForm管理

我有以下代码:

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)

delphi spring4d

2
推荐指数
1
解决办法
454
查看次数

Spring4D TDistinctIterator&lt;string&gt;.ToArray() 不起作用?

我想用Spring4DTDistinctIterator来获得不同ValuesTDictionary。因此我有以下代码:

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. 这是一个错误还是我应该以另一种方式使用迭代器来实现相同的结果?

delphi spring4d

2
推荐指数
1
解决办法
67
查看次数

如何使用spring4d中的IMultiCastEvent?

我试着开始使用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)

我很困惑%)请帮忙)

delphi spring4d

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

类型不满意的构造函数

使用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)

delphi spring4d

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

基于Spring4d接口的集合生命周期

spring4d中基于接口的集合如何处理其元素的生命周期?我想要实现的是当集合超出范围时,包含的对象也被释放,并且它们的析构函数被调用.目前还不确定是这种情况.

delphi spring4d

-2
推荐指数
1
解决办法
179
查看次数

标签 统计

delphi ×7

spring4d ×7

dunit ×1

interface ×1

unit-testing ×1