我是依赖注入和Play框架的忠实粉丝,但我很难看到这两者如何被一起利用。
Spring和Guice都有模块,但Play的工作方式使我很难看到DI在某些非常简单的情况下如何有益。
这方面的一个很好的例子是,Play期望JPA工作由与所讨论的实体相关联的静态方法完成:
@Entity
Person extends Model {
public static void delete(long id) {
em().find(id).remove();
}
//etc
}
因此,不需要像Spring J2EE应用程序那样将PersonManager
注入控制器。相反,控制器只需调用Person.delete(x)
。
显然,当存在与外部系统的接口时,DI是有益的,因为具体实现可以被模拟用于测试等,但是我认为对于自包含的Play应用程序没有太大的好处。
有没有人有任何好的例子?是否有人使用它将Manager
样式类注入Controller
s,以便在同一事务中完成许多操作,例如?
答案 0 :(得分:5)
我相信你写的这句话:
“有没有人有任何好的例子?有没有人用它来向控制器注入一个经理风格的类,以便在同一个事务中完成许多操作,例如?”
在回答DI问题之前,我应该注意一些事项:Play会自动管理交易。如果您检查model documentation,您将看到在请求开始时自动创建事务,并在结束时提交。您可以通过JPA回滚它,或者如果引发异常,它将被回滚。
我提到这一点是因为根据你的句子的措辞,我不确定你是否意识到这一点。
现在,关于DI本身,在我的(不那么广泛的)DI体验中,我看到它主要用于:
当然,还有更多场景,但这些可能涵盖了大多数实际使用情况。现在:
此处还有另外需要考虑的事项:我对Guice不太确定,但Spring不仅仅是DI,它还提供了许多依赖于DI模块的额外功能。所以也许你不想在Play中使用DI,但是你想利用Spring工具,他们会使用DI,虽然是间接的(通过xml配置)。
答案 1 :(得分:5)
我对Play的静态初始化方法拙见的问题!是因为它使测试更难。一旦您使用静态成员和带有HTTP消息数据(请求和响应)的对象来解决HTTP与对象方向问题,您需要通过使您的对象与其余请求松散耦合的能力来为每个请求创建新实例。您的项目类。
不同设计的一个很好的例子是servlets,它还扩展了一个基类,但它通过创建单个实例来解决问题(默认情况下为because there are configurations that enable more instances)。
我相信这两种方法的混合可能会更好,每个控制器的单例都会提供完整静态类的相同特性,并允许依赖注入某些类型的对象。但是,一旦需要在每个新请求中创建控制器,就不会有具有请求或会话范围的对象。此外,它可以通过反转依赖注入的控制来提高可测试性,从而允许任意注入点。
依赖性将通过容器或测试注入,可能使用模拟来处理之前很可能已经测试过的重物。
在我看来,这个静态模型推动开发人员远离测试控制器,因为扩展FunctionalTest启动应用服务器,从而支付重量级对象的价格,如存储库,服务,爬虫,http客户端等。我不想等待很多对象进行自举,只是为了检查一些代码是否在控制器上执行,测试应该快速而清晰,让开发人员喜欢他们作为他们的编程助手/指南。
答案 2 :(得分:2)
DI并不是在任何地方使用的终极解决方案......不要仅仅因为手中有DI而使用DI ......在游戏中,你不需要DI来开发控制器/模型等......但是有时它可能是一个很好的设计:IMO,你可以使用它,如果你有一个知名的界面服务,但你想在Play之外开发这项服务并在游戏外测试它甚至只用虚拟服务测试你的游戏项目为了不依赖于完整的服务实现。因此DI很有趣:你可以在游戏中松散地插入服务。事实上,这是DI afaik的原始用例...
答案 3 :(得分:2)
我刚刚撰写了一篇关于使用Google Guice设置Play Framework应用程序的博文。 http://geeks.aretotally.in/dependency-injection-with-play-framework-and-google-guice
我看到了一些好处,特别是当您的应用程序的某个组件需要基于特定上下文或类似内容的不同行为时。但我相信人们应该选择进入DI背景的内容。
答案 4 :(得分:1)
它再次表明,如果你确实有一个好处,你应该只使用依赖注入。如果你有复杂的服务,它很有用,但在很多情况下并非如此。请阅读play-documentation中有关模型的章节。
那么举个例子,你可以在游戏中使用DI。也许您必须进行复杂的计算,或者使用报告引擎创建pdf。在那里我认为DI非常有用,特别适用于测试。在那里我认为guice-module和spring-module非常有用,可以帮助你。
尼尔斯
答案 5 :(得分:0)
截至一年后有些变化,Play 2.1现在有support for dependency injection in controllers。这是他们的demo project using Spring 3,非常清楚地说明了这一点。
编辑:这是another example using Guice and Scala,如果这是你的毒药。