简体   繁体   English

Scala依赖注入用于单独配置的编译时间

[英]Scala Dependency Injection for compile time with separate configuration

Now firstly I realise the title is extremely broad, so let me describe the use case. 现在我首先意识到标题非常广泛,所以让我来描述用例。

Background: 背景:

I'm currently teaching myself Scala+Gradle (because I like the flexibility and power of gradle and the much more legible build files) 我现在正在自学Scala + Gradle(因为我喜欢gradle的灵活性和强大功能以及更易读的构建文件)

As such with learning new languages its often best to make applications that you can actually use, and being primarily a PHP (with Symfony) programmer and formerly a Java programmer, there are many patterns that could carry across from both paradigms. 因此,学习新语言通常最适合制作实际可以使用的应用程序,并且主要是PHP(使用Symfony)程序员和以前的Java程序员,这两种范例都有许多模式可以贯彻执行。

Use Case: 使用案例:

I'm writing an application where I am experimenting with a Provider+Interface(trait) layout, the goal is to define traits that encompass all the expected functionality for any particular type of component eg a ConfigReaderTrait and a YamlConfigReager as a provider. 我正在写在那里,我与提供商+接口(性状)布局实验的应用,目标是定义涵盖所有如任何特定类型的部件的预期功能特点ConfigReaderTraitYamlConfigReager作为供应商。 Theoretically the advantage of this would be to allow me to switch out core mechanisms or even architectural components with minimal effort, this allows for a great deal of R&D and experimenting. 从理论上讲,这样做的好处是可以让我以最小的努力切换核心机制甚至架构组件,这样就可以进行大量的研发和实验。

PHP Symfony Influence PHP Symfony影响力

Now currently I work as a pure PHP dev, and as such has been introduced to Symfony, which has a brilliant Dependency Injection framework where the dependencies are defined in yaml files, and can be delegated to sub directories. 现在我作为一个纯PHP开发工作,因此已经被引入Symfony,它有一个出色的依赖注入框架,其中依赖关系在yaml文件中定义,并且可以委托给子目录。 I like this, because unlike with SBT I am unphased by using different languages for different purposes (eg groovy with gradle for build scripts) and I want to maintain a separation of concerns. 我喜欢这个,因为与SBT不同,我不同的目的是使用不同的语言用于不同的目的(例如groovy with gradle for build scripts),我想保持关注点的分离。

Such that each type of interface/trait or bundle of related functionality should be able to have its own DI config, and I would prefer it separate from the scala code itself. 这样每种类型的接口/特性或相关功能包应该能够拥有自己的DI配置,我宁愿它与scala代码本身分开。

Now for Scala.... 现在为Scala ....

Obviously things are not the same across different languages, and if you don't embrace the differences you may aswell go back to the previous language and leave things at that. 显然,不同语言之间的情况并不相同,如果你不接受这些差异,你可以回到以前的语言,并留下一些东西。

That said, I am not yet convinced by the DI frameworks I see for scala. 也就是说,我还不相信我看到的用于scala的DI框架。

  • Guice for example is really a modified java framework (which is fine because scala can use java libs, but because they don't function in the entirely same paradigm of coding languages it feels as though scala's capabilities are not leveraged) 例如,Guice实际上是一个经过修改的java框架(这很好,因为scala可以使用java库,但因为它们不能在完全相同的编码语言范例中运行,所以感觉scala的功能没有被利用)
  • MacWire annoyed me a bit,because you had to define the dependencies in the files where you used them. MacWire让我恼火,因为你必须在你使用它们的文件中定义依赖项。 Which does not assist in my interface/provider concept. 这对我的界面/提供者概念没有帮助。
  • SubCut so far seems to be the best suited to what I would expect. 到目前为止,SubCut似乎是最适合我期望的。

But while going through all of this (and bare in mind this is all in the research phase, I havent used any of them yet) it seemed that DI in Scala is still very scattered, and in its infancy, by that I mean that there are different implementations with different applications, but not one flexible enough or power enough to compare to Symfonys DI. 虽然经历了所有这些(并且考虑到这一切都处于研究阶段,我还没有使用它们中的任何一个)似乎Scala中的DI仍然非常分散,并且在它的初期,我的意思是那里是不同的实现与不同的应用程序,但不是足够灵活或功率足以与Symfonys DI进行比较。 particularly not for my application. 特别是不适合我的申请。

Comments? 评论? Thoughts? 思考?

My 5 cents: 我的5美分:

I have actually stopped using dependency injection frameworks after switching to Scala from Java. 在从Java切换到Scala之后,我实际上已经停止使用依赖注入框架。

The language allows for a few nice ways of doing it without a framework (multiple parameter lists and currying as well as the mixins for doing injection the way the 'cake pattern' does) and I find myself more and more just using constructor or method parameter based injection as it clearly documents what dependencies a given piece of logic has and where it got those dependencies from. 这种语言允许一些很好的方法来做这个没有框架(多个参数列表和currying以及用于按照'蛋糕模式'进行注入的mixin)并且我发现自己越来越多地使用构造函数或方法参数基于注入,因为它清楚地记录了给定逻辑片段的依赖关系以及从哪里获得这些依赖关系。

It's also fairly easy to create different modules sets of implementations or factories for implementations using Scala object s and then selecting between those at runtime. 使用Scala object为实现创建不同的模块实现或工厂集合,然后在运行时选择它们也相当容易。 This will give you the guarantee that it wont compile unless there is an implementation available, as opposed to the big ones in Java-land that will fail in runtime, effectively pushing a compile time problem into runtime. 这将保证它不会编译,除非有可用的实现,而不是Java-land中的大型将在运行时失败,有效地将编译时问题推入运行时。

This also removes the 'magic' of how dependencies are created and wired (reflection, runtime weaving, macros, XML, binding context to thread local etc). 这也消除了如何创建和连接依赖关系(反射,运行时编织,宏,XML,绑定上下文到线程本地等)的“魔力”。 I think this makes it much easier for new developers to jump into a project and understand how the codebase is interconnected. 我认为这使新开发人员更容易进入项目并了解代码库是如何互连的。

Regarding declaring implementations in non-code like XML I have found that projects rarely or never change those files without making a new release so then they might as well be code with all the benefits that bring (IDE support, performance, type checking). 关于在像XML这样的非代码中声明实现,我发现项目很少或永远不会在没有新版本的情况下更改这些文件,因此它们也可能具有带来所有好处的代码(IDE支持,性能,类型检查)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM