Jacek Laskowski 57 Posted March 20, 2019 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
Guest Posted March 20, 2019 (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 March 20, 2019 by Guest Share this post Link to post
Stefan Glienke 2002 Posted March 20, 2019 (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 March 20, 2019 by Stefan Glienke Share this post Link to post
Guest Posted March 20, 2019 (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 March 20, 2019 by Guest Share this post Link to post
Stefan Glienke 2002 Posted March 20, 2019 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? 1 Share this post Link to post
Guest Posted March 20, 2019 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. Share this post Link to post
Jacek Laskowski 57 Posted March 20, 2019 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
Stefan Glienke 2002 Posted March 20, 2019 (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 March 20, 2019 by Stefan Glienke Share this post Link to post
Rudy Velthuis 91 Posted March 20, 2019 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
Jacek Laskowski 57 Posted March 21, 2019 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
Stefan Glienke 2002 Posted March 21, 2019 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
Rollo62 536 Posted March 23, 2019 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
Stefan Glienke 2002 Posted March 23, 2019 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
Guest Posted March 24, 2019 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