#1 2020-06-17 14:15:16

damiand
Member
From: Greece
Registered: 2018-09-21
Posts: 94

Training sample for lazy dependency injection

I admit that I'm a bit confused by the documentation on the topic of lazy DI. So I modified the Sample 14 to try to figure it out. Besides the ICalculator I created another interface (IMyTestService) for the actual service contract. The exposed service method is named DoTheJob. The source file is here:
https://gist.github.com/dadim/c17579859 … erface-pas

In the server implementation code (based on the In Memory Server), located here:
https://gist.github.com/dadim/c17579859 … memory-pas
I created a TMyTestService class descendant of TInjectableObjectRest which implements the IMyTestService interface. This has a private property fCalculator of ICalculator type and a public read only property (Calculator), which reads it. In the implementation code of the function DoTheJob (lines 36 - 40) I try to resolve an injection to the fCalculator property, but with no success:

function TMyTestService.DoTheJob(n1, n2: integer): integer;
begin
  if Server.Services.Resolve(ICalculator, fCalculator) then
    Result := fCalculator.Add(n1,n2)
end;

When the client calls the DoTheJob service method, the if condition is false and the result is returned with its default, initialized value of 0. How can I inject an instance of the TServiceCalculator class to the fCalculator property?

The source code of the main form of the client (if is it of any importance), is here:
https://gist.github.com/dadim/c17579859 … ntmain-pas

Offline

#2 2020-06-17 14:36:13

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,182
Website

Re: Training sample for lazy dependency injection

If you result in the execution method, no need to put the ICalculator variable as fCalculator instance variable.
Use a local variable.

If you want an instance fCalculator variable, then you can resolve it once in the service constructor, or by using the auto-inject feature.

Use a local variable or an instance variable should better be made depending of the kind of service.
A sicPerSession or sicPerUser should be a local variable (it would change depending on the client connected).
A sicShared could be an instance variable, since it won't change.

Offline

#3 2020-06-17 14:40:47

Márcio Baroni
Member
From: Brasil
Registered: 2015-10-07
Posts: 28

Re: Training sample for lazy dependency injection

Register the interface

ServiceDefine (TServiceCalculator, [ICalculator], sicShared);

Offline

#4 2020-06-17 15:40:45

damiand
Member
From: Greece
Registered: 2018-09-21
Posts: 94

Re: Training sample for lazy dependency injection

Thank you both ab and Marcio for your help. smile I added the line you proposed Marcio and the problem solved. This is, I suppose, the auto-inject feature ab mentioned above. It seems reasonable, although I initially found it strange, since the ICalculator service is going to be used - at least in this example - inside the server and not from a client. But from a SOA perspective, it is a sort of service usage I presume, regardless weather it is within the server context or from a client. roll

ab I suppose that this ICalculation service registration is mandatory for the Resolve method to work, regardless weather is going to target an instance or a local variable.

Last edited by damiand (2020-06-17 15:41:37)

Offline

#5 2020-06-17 17:21:53

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,182
Website

Re: Training sample for lazy dependency injection

Yes, of course, as the documentation stated, you need to register the service!

But try to understand the meaning of injection, and that if you use an instance variable, you need to resolve it once.
And resolving it in the method is not thread-safe, so should be avoided.

Offline

#6 2020-06-17 18:28:33

damiand
Member
From: Greece
Registered: 2018-09-21
Posts: 94

Re: Training sample for lazy dependency injection

I understand that in a case of an instance variable the resolve has to be done once, so the method is not a good place to happen. You advise me to use either the service constructor (by overriding CreateWithResolverAndRest? ), or the auto-inject feature. Can you please give me an example or a reference about the auto-inject feature usage?

Offline

#7 2020-06-17 19:38:58

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,182
Website

Re: Training sample for lazy dependency injection

Please check the doc again.

Offline

#8 2020-06-18 09:28:41

damiand
Member
From: Greece
Registered: 2018-09-21
Posts: 94

Re: Training sample for lazy dependency injection

ab you are right. RTFM! tongue As it is stated here I needed the interface property to be published and not public as I had it in my initial class definition. Now I can access the injected Calculation interface directly in the method without trying to resolve it manually.

For anyone it may concern (this is a training topic wink ), I updated the source code of the server implementation in the gist (see the first message above).

Offline

#9 2020-06-18 09:32:35

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,182
Website

Re: Training sample for lazy dependency injection

Thanks for the feedback.

Offline

Board footer

Powered by FluxBB