4 ms·
> With compile-time DI, you make service classes accept lower level dependencies as constructor parameters. In Scala, constructor parameters are accessible from
by inglor 10y ago
> With compile-time DI, you make service classes accept lower level dependencies as constructor parameters. In Scala, constructor parameters are accessible from regular methods, so most of the time, these services could be completely stateless. This approach is also advocated by several Java (and .NET) experts, but it's by no means mainstream. Interestingly, Scala developers have an advantage over Java/C# users, because they can significantly simplify the implementation by combining a macro-based library with lazy definitions:
Asking for a dependency explicitly is service location not dependency injection. Your code there does not solve anything better than a regular service locator in a constructor would. The point of DI is that it's abstracted from the user code and the user doesn't have to care about these `wire` calls and can test it "as if dependencies were just passed regularly".
- sreque 10y agoI don't think you're understanding what the author was saying. The author is advocating for constructor-based dependency injection, which incidentally, I also advocate for. There is a macro-based library in Scala, MacWire, that helps write the constructor calls for you, essentially acting as an auto-wire-like replacement to Spring and Guice, except that it does all its work at compile time. This mean you catch errors much earlier in the build and deploy process.
- inglor 10y agoWhere are the wire calls performed? Not in the constructor but in an initialization file?
- sreque 10y agoI'm not familiar with MacWire, but I believe it's powered by macros. You can think of a macro as a function that runs at compile time. It's input is a syntax tree representing some code, and it's output is an arbitrary syntax tree representing code. The compiler, while processing source code, will recognize places where a macro should be invoked on some syntax. It will call the macro on that syntax, then replace the syntax with the output of the macro. In this sense, you can imagine a macro that takes in the source code for a class that has wire calls, and rewrites the wire calls into object constructor calls based on introspection of the syntax and types in the class. If you're familiar with C macros, they are technically the same kind of thing, although very basic, error prone, and unpleasant to work with. If you want to learn more about macros, I would recommend starting with a simpler, more sane macro system like one in Scheme, or, if you want something that looks more like Java, Nemerle (http://www.nemerle.org/About http://www.nemerle.org/About). Scala's macro system has a bit of a bolt-on feel since the language wasn't designed from the ground up for macros. That said, I applaud Scala's effort to try to figure out how to integrate macros into their core language and hope they are successful in the future with Scala Meta (http://scalameta.org/ http://scalameta.org/)