Jonas Bonr 的依赖注入策略似乎有限制——但也许我不明白它
我已经读过这篇文章好几次了:
http: //jonasboner.com/2008/10/06/real-world-scala-dependency-injection-di.html
我想我明白了。然而,有些事情我不太明白。
查看他的 UserService 示例,我发现他设置了 UserRepositoryComponent 来封装 UserRepository。但我不明白的是为什么 UserRepositoryComponent 扮演两个角色:它封装 UserRepository 并提供对 UserRepository 对象的引用。
我试图想象如果我想创建一个依赖于两个 UserRepository 实例的服务,我将如何使用此模式。也许新服务的工作是将用户从“源”UserRepository 复制到“目标”UserRepository。所以我想象的是这样的:
trait CopyUserServiceComponent {
val source: UserRepositoryComponent
val destination: UserRepositoryComponent
class CopyUserServiceComponent {
...
}
}
但这与原来的模式不同。在本例中,我在组件本身中定义依赖项,而不是从其他组件继承它们。但在我看来,这是正确的方法:组件应该声明它们的依赖项,而不是它们包含的服务的实例。
我在这里缺少什么?
I've read this article several times:
http://jonasboner.com/2008/10/06/real-world-scala-dependency-injection-di.html
I think that I get it. However there's something that I'm not quite getting.
Looking at his UserService example, I see that he's set up UserRepositoryComponent to encapsulate UserRepository. But what I don't understand is why UserRepositoryComponent plays two roles: it encapsulates UserRepository and also offers a reference to a UserRepository object.
I'm trying to imagine how I would use this pattern if I wanted to create a service that depends on two UserRepository instances. Maybe the job of the new service is to copy users from a "source" UserRepository to a "destination" UserRepository. So I'm imagining something like this:
trait CopyUserServiceComponent {
val source: UserRepositoryComponent
val destination: UserRepositoryComponent
class CopyUserServiceComponent {
...
}
}
But this is different from the original pattern. In this case I'm defining the dependencies in the component itself instead of inheriting them from some other component. But this seems to me to be the right way to do it: the components should declare their dependencies, not instances of their included services.
What am I missing here?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
蛋糕模式不使用继承来声明依赖关系。您在
UserServiceComponent
中看到任何“扩展”吗?但这正是蛋糕模式的作用:声明依赖关系!也许如果示例包含 def userRepositoryFactory = new UserRepository 而非 val userRepository = new UserRepository ,情况会更清楚吗?
那么,让我们回到你的例子:
让我们看看我们不能用它做的事情:
另一方面......
编辑
补充答案,让我们考虑两个不同的需求:
UserRepository
实例。在这种情况下,您在错误的级别应用了该模式。在 Jonas 的示例中,
UserRepository
处于工厂提供单例的级别。因此,在这种情况下,您不会执行
UserRepository
和UserRepositoryComponent
,而是执行UserRepositoryFactory
和UserRepositoryFactoryComponent
。UserRepository
。在这种情况下,只需执行以下操作:
The cake pattern doesn't use inheritance to declare dependencies. Did you see any "extend" in
UserServiceComponent
?But that's exactly what the cake pattern does: declare dependencies! Perhaps if the example contained
def userRepositoryFactory = new UserRepository
instead ofval userRepository = new UserRepository
, that would have been more clear?So, let's go back to your example:
Let's see the things we can't do with that:
On the other hand...
EDIT
Complementating the answer, let's consider two different needs:
UserRepository
.In this case, you are applying the pattern at the wrong level. In Jonas' example,
UserRepository
is at the level of a factory-providing singleton.So, in that case, you wouldn't do
UserRepository
andUserRepositoryComponent
but, say,UserRepositoryFactory
andUserRepositoryFactoryComponent
.UserRepository
.In this case, just do something like this:
我认为,乔纳斯在他的文章中提到了一种广泛接受的构建可扩展应用程序的方法称为复合软件构建,用几句话可以解释如下:整个应用程序(在元级别上编排)是由独立组件构建的程序集,而这些组件又是其他组件和服务的组合。就复合软件而言,'cake'(示例中的
ComponentRegistry
对象)是组件('UserServiceComponent'和'UserRepositoryComponent')等的集合。而在示例中组件包含服务实现,这在现实世界中几乎不可能发生。在您的示例中,您不需要定义内部类 - 您可以将工作流程放入普通方法中:
它完全符合原始模式 - 蛋糕的基本功能不仅是通过自类型注释指定依赖项,而且还能够从具体实现中抽象出来,直到您需要从组件构建程序集的那一刻。
I assume, Jonas in his article refers to a widely accepted methodology of building scalable applications called Composite Software Construction that in a few words can be explained as follows: entire application (orchestrated on a meta-level) is an assembly built of independend components, which in their turn are compositions of other components and services. In terms of composite software, 'cake' (
ComponentRegistry
object in the example) is an assembly of components ('UserServiceComponent' and 'UserRepositoryComponent') etc. Whilst in the example components enclose service implementations it can hardly happen in the real-world.In your example you don't need to define an inner class - you can put your workflow in an ordinary method:
It perfectly conforms to original pattern - essential feature of the cake is not [only] specifying dependencies via self-type annotations, but also ability to abstract from the concrete implementation, till the moment when you need to build an assembly from the components.