Resolve generic type by qualified name

Issue #341 open
MasterpieceDeveloper created an issue

You described the problem in

https://delphisorcery.blogspot.com/2017/02/generics-modules-and-typeinfo.html

It is very relevant, how can I interfere in the process of registering a type that is in a package, they will receive it in another package

class constructor TSomeBaseClass<I>.Create;

GlobalContainer.RegisterType<IProcessor<I>>(

‌ function: IProcessor<I>

‌ begin

‌ Result := TProcessor<I>.Create;

‌ end

).Implements(TypeInfo(IProcessor<I>)).AsSingletonPerThread;

in another package

ServiceLocator.GetService<IProcessor<ISomeIntf>>….

Comments (3)

  1. Stefan Glienke repo owner
    • changed status to open

    I know what you mean - however the code you present is impossible in Delphi because we cannot register open generic types. So the registration would have to happen with IProcessor<ISomeIntf>/TProcessor<ISomeIntf> (callback is not necessary in that case btw).

    To solve that issue the internal mechanism in the type registry has to be refactored - a task that also affects other pieces and enables other features to be implemented.

    While I originally wanted to work on this sooner and have already started working on it the more important work that was done for 2.0 so far and will hopefully ready soon(tm) was all the work on the collections to improve their performance in all areas (executable speed, binary size, compilation speed).

  2. MasterpieceDeveloper reporter

    These were registration attempts in different ways, until I read your article and understood the source of the problem. It is assumed

    GlobalContainer.RegisterType(TProcessor<I>.ClassInfo).Implements(TypeInfo(IProcessor<I>), string.Empty).AsSingletonPerThread;

    We can't imagine working without Spring4D anymore, and your work on collections is certainly more important.

    However, the ability to receive a service regardless of its location determines the architecture of projects…

    Thank god for your talent.

  3. MasterpieceDeveloper reporter

    Made for trial

    fDefaultRegistrationsQualifiedName: IDictionary<string, PTypeInfo>;

    procedure TComponentRegistry.RegisterDefault

    ...

    fDefaultRegistrations[serviceType] := model;

    if not fDefaultRegistrationsQualifiedName.ContainsKey(serviceType.TypeName) then

    ‌ fDefaultRegistrationsQualifiedName.Add(serviceType.TypeName, serviceType);

    function TComponentRegistry.FindDefault

    var

    P: PTypeInfo;

    if fDefaultRegistrations.TryGetValue(serviceType, Result) or fServiceTypeMappings[serviceType].TryGetSingle(Result) then

    ‌ Exit;

    if fDefaultRegistrationsQualifiedName.TryGetValue(serviceType.TypeName, P) then

    ‌ Result := fDefaultRegistrations[P];

    function TComponentRegistry.HasService

    Result := fServiceTypeMappings.ContainsKey(serviceType) or

    ‌ fDefaultRegistrationsQualifiedName.ContainsKey(serviceType.TypeName);

    function TComponentRegistry.HasDefault(serviceType: PTypeInfo): Boolean;

    begin

    Result := fDefaultRegistrations.ContainsKey(serviceType)

    ‌ or fDefaultRegistrationsQualifiedName.ContainsKey(serviceType.TypeName)

    ‌ or (fServiceTypeMappings[serviceType].Count = 1);

    end;

    but I, of course, do not know the full depth of the framework and where it will shoot…

  4. Log in to comment