You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: 2024_12_09_dependency-injection.md
+6-6Lines changed: 6 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -22,7 +22,7 @@ Find time to modernize dependency injection in some services. The previous versi
22
22
However, for relatively small applications, it is possible to live with.
23
23
24
24
25
-
If we switch to type-driven context resolving (i.e., use AppContext[Service1] instead of appContext.service1 ), we will solve the modularization problem.
25
+
If we switch to type-driven context resolving (i.e., use `AppContext[Service1]` instead of `appContext.service1` ), we will solve the modularization problem.
26
26
27
27
The first look was at the approach described by @odersky in https://old.reddit.com/r/scala/comments/1eksdo2/automatic_dependency_injection_in_pure_scala/.
(complete code is available in the repository: https://github.com/rssh/scala-appcontext )
183
183
184
-
We separate `AppContextProvidersSearch` and `AppContextProviders` because we don't want to trigger AppContextProviders' implicit generation during implicit search outside of service instance generation.
184
+
We separate `AppContextProvidersSearch` and `AppContextProviders` because we don't want to trigger `AppContextProviders` implicit generation during implicit search outside of service instance generation.
185
185
Note that Scala currently has no way to make a macro that generates a given instance to fail an implicit search silently. We can only make errors during the search, which will abandon the whole compilation.
186
186
187
187
Can we also remove the boilerplate when defining the implicit AppContext provider?
@@ -209,7 +209,7 @@ object UserSubscription {
209
209
210
210
But this will still be boilerplate: We must enumerate dependencies twice and write trivial instance creation. On the other hand, this instance creation is not entirely meaningless: we can imagine the situation when it's not automatic.
211
211
212
-
To minimize this kind of boilerplate, we can introduce a convention for AppContextProviderModule, which defines its dependencies in type and automatic generation of instance providers:
212
+
To minimize this kind of boilerplate, we can introduce a convention for `AppContextProviderModule`, which defines its dependencies in type and automatic generation of instance providers:
213
213
214
214
```Scala
215
215
traitAppContextProviderModule[T] {
@@ -286,7 +286,7 @@ object AppContext {
286
286
```
287
287
288
288
289
-
And let's deploy a simple convention: if the service requires `AppContext.Cache` as a dependency, then we consider this service cached. I.e., with manual setup of AppContextProvider this should look like this:
289
+
And let's deploy a simple convention: if the service requires `AppContext.Cache` as a dependency, then we consider this service cached. I.e., with manual setup of `AppContextProvider` this should look like this:
290
290
291
291
```Scala
292
292
objectFuelUsage {
@@ -347,9 +347,9 @@ println(c3.doSomething())
347
347
348
348
What will be printed?
349
349
350
-
The correct answer is “dep1:module:dep2:local”, because resolving of Dependency1 from the companion object of Dependency1 will be preferred over resolving from the AppContextProvider companion object. Unfortunately, I don’t know how to change this.
350
+
The correct answer is `“dep1:module:dep2:local”`, because resolving of `Dependency1` from the companion object will be preferred over resolving from the `AppContextProvider` companion object. Unfortunately, I don’t know how to change this.
351
351
352
-
We can add a check to determine whether supplied providers are needed. Again, unfortunately, we can’t add it ‘behind the scenes' by modifying the generator of AppContextProvider because the generator is inlined in the caller context for the component instance, where all dependencies should be resolved.
352
+
We can add a check to determine whether supplied providers are needed. Again, unfortunately, we can’t add it ‘behind the scenes' by modifying the generator of `AppContextProvider` because the generator is inlined in the caller context for the component instance, where all dependencies should be resolved.
353
353
We can write a macro that should be called from the context inside a component definition. This will require the developer to call it explicitly.
354
354
355
355
I.e., a typical component definition will look like this:
0 commit comments