Closed valorad closed 1 year ago
@valorad - Thanks a lot for the feedback and a very clear issue description.
Singletons are registered in a global context, once it is initialized for accountServiceInstance
, its result will be cached and reused whenever there is an request to initialize the IAccountService
. I haven't documented this mechanism clearly, and I am going to add this part.
The following features are not supported for singleton, and here are the reasons:
MockServiceModule
used in test classes, the original service is not intended to be initialized. So the singleton replacement method is not necessarily provided in order to prevent abuse. I can provide one but I hesitated due to this reason. I also need strong evidence to know this is really a limitation before implementing it.In your case, it will work if the IAccountService
is registred as a scoped, or transient lifetime inside MockServiceModule
.
public with sharing class MockServiceModule extends DI.Module {
public override void configure(DI.ServiceCollection services) {
services.addScoped('IAccountService', 'MockAccountService'); // use addScoped()
}
}
If you have new thoughts, please just let me know. And sorry to respond you 4 days late, I am busy at a new library these days. It is published now, I think it is the best SOQL query builder you can ever find in github, wish you can also have a try https://github.com/apexfarm/ApexQuery.
I have just added a new section 1.2 Singleton Lifetime Caveat, to explain the singleton mechanism behind and how to mitigate the issue.
@inksword Got it. Thanks for your thorough explanation!
When I try to get two modules with the same service interface in the same context, the latter service is not retrieved correctly.
For example, when I run this in Dev console:
I get the exact same result for
defaultResult
andmockResult
While the expected result should be different.
However, when I comment out all the code for
defaultResult
, then this time the mockResult is as expected.Here are my service implementations