2012-03-31 11 views
8

Es ist möglich, eine Klasse mit einem Parameter zu registrieren, von dem erwartet wird, dass er vom Erstellungsort übergeben wird?Delphi - Wie übergibt man einen Parameter vom Instantiator an einen Konstruktor im spring4d Dependency Injection Framework?

Ich weiß es so etwas wie dies geschehen kann:

GlobalContainer.RegisterType<TUserProcessor>.Implements<IUserUpgrader>. 
AsTransient.DelegateTo(
    function: TUserProcessor 
    begin 
     Result := TUserProcessor.Create(GetCurrentUser); 
    end 
); 

Aber es werden die Parameter an den Ausführungskontext binded wo der Container registriert wird und nicht, wo das Objekt gets intantiated.

So etwas ist zum Beispiel möglich?

GlobalContainer.Resolve<IMathService>([FCurrentUser]); 

Ich kenne einige peoble Anwalt sehr einfache Konstrukteure haben, aber es gibt Zeiten, wenn ein Konstruktor Parameter zu gehen deutlich die Art und Weise sieht:

  1. Das Objekt der Objektparameter arbeiten konstruiert muss, Also muss die Referenz erfüllt sein. Der Parameter macht diese Einschränkung auch deutlich sichtbarer, wenn man die Klasse betrachtet.

  2. Sie können die Referenz in einer Methode oder Eigenschaft zuweisen und heben und Ausnahme in jeder anderen Methode, wenn Sie versuchen, das Objekt zu nutzen, ohne dass die Zuordnung zu machen .. Ich weiß nicht, wie diese Art von Code zu schreiben es einfach einem Zeitverschwendung, verwenden Sie einfach den Konstruktorparameter und überprüfen Sie dort. Weniger Code, desto besser IMO.

  3. Auch das übergebene Objekt ist lokal für das Objekt, das das neue Objekt unter Verwendung des Containers (zum Beispiel ein Transaction-Objekt) konstruiert und einen Zustand hat (es ist kein neues Objekt, das ich mit dem Container bekommen kann).

+0

Ich weiß nicht, von einer Überlastung des '' TContainer.Resolve ein Array-Parameter in Spring4D akzeptieren. Vermisse ich etwas? – menjaraz

+0

@menjaraz Es war nur und die Idee, wie es implementiert werden könnte (sicher kann es mit RTTI donde sein) –

+0

Ok, das klingt wie eine Feature-Anfrage. Warum posten Sie das nicht auch für die [spring4d Google Group] (http://groups.google.com/group/spring4d)? – menjaraz

Antwort

7

Ich habe Resolver-Overrides wie in Unity hinzugefügt.

So können Sie schreiben:

program Demo; 

{$APPTYPE CONSOLE} 

uses 
    Classes, 
    Spring.Container, 
    Spring.Container.Resolvers; 

type 
    IUserUpgrader = interface 
    ['{ADC36759-6E40-417D-B6F7-5DCADF8B9C07}'] 
    end; 

    TUser = class(TObject); 

    TUserProcessor = class(TInterfacedObject, IUserUpgrader) 
    public 
    constructor Create(AUser: TUser); 
    end; 

constructor TUserProcessor.Create(AUser: TUser); 
begin 
    Writeln('called constructor with passed user'); 
end; 

begin 
    GlobalContainer.RegisterType<TUserProcessor>.Implements<IUserUpgrader>; 
    GlobalContainer.Build; 

    GlobalContainer.Resolve<IUserUpgrader>(
    TOrderedParametersOverride.Create([TUser.Create])); 

    GlobalContainer.Resolve<IUserUpgrader>(
    TParameterOverride.Create('AUser', TUser.Create)); 

    Readln; 
end. 
0

Sie könnten diesen Thread ansehen: https://forums.embarcadero.com/message.jspa?messageID=440741

Ich habe eine Implementierung auf diese im Rahmen getan und es in meinem Code verwenden. Wenn du es willst, schicke ich es dir. Denken Sie daran, dass dies nicht möglich ist, wenn sie Funktionen wie diese in der Codebasis hinzufügen. Baoquan hat meinen Code.

Diese Implementierung behandelt auch, wenn Sie versuchen, ohne alle erforderlichen Parameter aufzulösen, und gibt Ihnen eine Ausnahme mit den fehlenden Parametern.

Sie verwenden es wie folgt aus:

ServiceLocator.GetService<ISomeObj>(ServiceParameters['paramname1',value1]['paramname2',value2]..); 

Wert als TValue gespeichert und kann alles sein.

private 
    [ContainerParameter('paramname1')] 
    FYourValue1: ...; 
    [ContainerParameter('paramname2')] 
    FYourValue2: ..; 

Sie können

[ContainerParameter] 
FYourValue1:.. 

Aber dann Parameter haben auch tun 'FYourValue1' als Name:

die Parameter mit Ihrer Klasse Registrierung ist mit Attributen wie dies getan.