delphi - how to pass a parameter from the instantiator to a constructor in the spring4d dependency injection framework?

廉价感情. 提交于 2019-11-30 09:24:23

I have added resolver overrides as in Unity.

So you can write:

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.

Edit 17.09.2018:

This changed quite some while ago and Resolve is accepting parameters via array of TValue. You can either pass values directly there which then have to match exactly the parameter list in the ctor. For only partially filling the parameters you can use TNamedValue or TTypedValue from Spring.pas

Anyway I suggest using factories to be injected and consumed by your code and not reaching into the container (global one or not) Resolve method.

You could check out this thread: https://forums.embarcadero.com/message.jspa?messageID=440741

I've done an implementation on this in the framework and use it in my code. If you want it, I'll send it to you. Keep in mind that this is not how it might be done when and if they add functionality like this in the codebase. Baoquan has my code.

This implementation also handles if you try to resolve without all needed parameters, and gives you an exception showing the missing parameters.

You use it like this:

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

Value is stored as TValue and can be anything.

Registering the parameter with your class is done with attributes like this:

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

You can also do

[ContainerParameter]
FYourValue1:.. 

But then your parameter have 'FYourValue1' as name.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!