Jump to content
Jacek Laskowski

Spring4D and IEqualityComparer<T>

Recommended Posts

Is it possible to register a generic class implementing the delphi IEqualityComparer<T> in the Spring container? This interface does not have a GUID and RegisterType generates an error. How to do it?

Share this post


Link to post
Posted (edited)
type
  IStringEqualityComparer = interface( IEqualityComparer<string> )
    ['{<INSERT_A_GUID>}']
  end;

The generic interface itself is not a type at all (ask the RTTI at runtime)

Edited by Schokohase

Share this post


Link to post
Posted (edited)

Does the implementing class itself has dependencies the container should build? Otherwise simply use RegisterInstance.

RegisterType with DelegateTo currently does not work although it could let it pass without guid because it then internally does not need it.

 

It's an interesting point though - the fact it needs a GUID is only internally because when creating class instances and resolving them as interface it uses Supports.

However since Delphi XE there is some additional type info available for the classes interface table so the container could find the correct one only via the interface type info.

I will put that on my list to research to relax that requirement in the future.

 

8 minutes ago, Schokohase said:

The generic interface itself is not a type at all

Oh, how I wish we could use open generics in Delphi ...

 

Edited by Stefan Glienke

Share this post


Link to post
Posted (edited)
18 minutes ago, Stefan Glienke said:

Oh, how I wish we could use open generics in Delphi ...

I guess we will have an open-source delphi compiler before that ...

Edited by Schokohase

Share this post


Link to post
3 minutes ago, Schokohase said:

I guess we will have an open-source delphi compiler before that ...

Is that before or after hell freezes over or easter and christmas are on the same day?

  • Like 1

Share this post


Link to post
6 minutes ago, Stefan Glienke said:

Is that before or after hell freezes over or easter and christmas are on the same day?

I heard some rumors it should be released two days after hell freeze around tea time.

  • Haha 1

Share this post


Link to post
2 hours ago, Stefan Glienke said:

Does the implementing class itself has dependencies the container should build? 

 

Yes, I have class with IEqualityComparer<T> in constructor, so I need the container to be able to resolve this interface... but this is impossible?


 

TMyClass<T> = class(TInterfacedObject, IMyInterface)
  constructor Create(const aKeyComparer : IEqualityComparer<T>);
end;

 

 

Share this post


Link to post
Posted (edited)

I meant the implementing class of the comparer or are you using the default from Generics.Defaults?

 

Then just RegisterInstance(TEqualityComparer<whatever>.Default());

 

Or make an overload without parameter where you create the default comparer and mark that one with [Inject] for the container to use that one because imo a comparer if it does not have dependencies itself falls into the category of a createable thus does not need to be injected.

Edited by Stefan Glienke

Share this post


Link to post
6 hours ago, Schokohase said:

I guess we will have an open-source delphi compiler before that ...

Like FPC? Not Delphi, but the closest there is.

Share this post


Link to post
15 hours ago, Stefan Glienke said:

I meant the implementing class of the comparer or are you using the default from Generics.Defaults?

 

Then just RegisterInstance(TEqualityComparer<whatever>.Default());

 

Or make an overload without parameter where you create the default comparer and mark that one with [Inject] for the container to use that one because imo a comparer if it does not have dependencies itself falls into the category of a createable thus does not need to be injected.

 

Ok, I paste more code with real example:

 

program s4dgic;

uses
  System.Generics.Defaults,
  Spring.Collections,
  Spring.Container,
  System.SysUtils;

{$APPTYPE CONSOLE}
{$R *.res}

type
  TBaseClass<T, V> = class(TInterfacedObject)
  private
    fDict: IDictionary<T, V>;
  public
    constructor Create(const aComparer: IEqualityComparer<T>); virtual;
  end;

constructor TBaseClass<T, V>.Create(const aComparer: IEqualityComparer<T>);
begin
  inherited Create;
  fDict := TCollections.CreateDictionary<T, V>(aComparer);
end;

type
  RKey = record
    FieldA: Integer;
    FieldB: String;
  end;

  TMyEqualityComparer = class(TEqualityComparer<RKey>)
  public
    function Equals(const Left, Right: RKey): Boolean; override;
  end;

function TMyEqualityComparer.Equals(const Left, Right: RKey): Boolean;
begin
  Result := (Left.FieldA = Right.FieldA) and (Left.FieldB = Right.FieldB);
end;

type
  IMyIntf = interface ['{874B15D9-675E-428B-906A-D526FCC3AE0D}']
  end;

  TMainClass = class(TBaseClass<RKey, TObject>, IMyIntf)
  public
    constructor Create(const aComparer: IEqualityComparer<RKey>); override;
  end;

constructor TMainClass.Create(const aComparer: IEqualityComparer<RKey>);
begin
  inherited Create(aComparer);
end;

var
  C: TContainer;
  I : IMyIntf;
  
begin
  try
    C := TContainer.Create;

    >>>>>  how to register required types?   <<<<

    C.RegisterType<TMainClass>.Implements<IMyIntf>;
    C.Build;
    I := C.Resolve<IMyIntf>;
    C.Free;
    Readln;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;

end.

 

Share this post


Link to post

No point of injecting the comparer via container. Make a parameterless ctor where you create it. I suggest reading Nick hodges book on DI about the difference of "createables" and "injectables".

Share this post


Link to post
On 3/20/2019 at 2:30 PM, Stefan Glienke said:

Is that before or after hell freezes over or easter and christmas are on the same day?

Thinking about Roslyn,  it seems the hell had frozen already.

Share this post


Link to post
18 minutes ago, Rollo62 said:

Thinking about Roslyn,  it seems the hell had frozen already.

No, it was a logical consequence of people not only thinking up to the next fiscal quarter and realizing that not rewriting the compiler would end in a dead end rather sooner than later.

That combined with a company that has enough resources to put quite some people on a project for years. But we are getting dangerously close to becoming political 😉

Share this post


Link to post
15 hours ago, Rollo62 said:

Thinking about Roslyn,  it seems the hell had frozen already.

Yes, when you remember the time of Steve B. 

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×