打破 Dagger 中的循环依赖
Posted
技术标签:
【中文标题】打破 Dagger 中的循环依赖【英文标题】:Breaking cyclic dependency in Dagger 【发布时间】:2015-10-13 03:23:03 【问题描述】:我对 dagger 很陌生——我什至不知道它是否适用于我的应用程序
我有一个搜索页面,它返回有关给定名人的最新消息。
我编写了一个测试来验证当我们搜索一个受欢迎的名人时结果是否会显示在页面上。
page
有一个searchField
,它的构造函数中需要page
,因此我用于测试的网络驱动程序可以选择它。
名人搜索页面测试
public class CelebritySearchPageTest
@Test
public void testSearchResultsForKevinBaconVerifyHisPopularity()
CelebritySearchPage searchPage = new CelebritySearchPage();
searchPage.searchFor("Kevin Bacon");
Assert.assertTrue(searchPage.getNumberOfResults() > 9999999, "Verify that Kevin Bacon is still relevant");
名人搜索页面
public class CelebritySearchPage extends Page
@Inject
@Named("search field")
TextField searchField;
public void searchFor(String text)
searchField.setText(text);
// ...
public int getNumberOfResults()
// ...
名人搜索页面模块
@Module(injects = CelebritySearchPage.class)
public class CelebritySearchPageModule
@Provides
@Named("search field")
public TextField provideSearchField()
return new TextField(/* How do I get the page? */, "#searchField");
页面
public abstract class Page
// ...
文本字段
public class TextField
protected Page page;
protected String selector;
public TextField(Page page, String selector)
this.page = page;
this.selector = selector;
public void setText(String text)
// ...
问题是page
需要searchField
,但searchField
需要page
。如何克服这种循环依赖?
我无法在 CelebritySearchPage 中初始化 searchField
【问题讨论】:
为什么TextField需要Page? @AndreasFrischetextField.getFullSelector()
致电page.getFullSelector()
好的。也许然后注入一个 FullSelectorHolder 。或使用 Lazy:“有时您需要延迟实例化对象。对于任何绑定 T,您可以创建一个延迟实例化的延迟实例化,直到第一次调用 Lazy考虑一下:
名人搜索页面
public class CelebritySearchPage extends Page
private final Lazy<TextField> searchField;
// always prefer constructor injection
// avoid @Named if possible, since the compiler cannot check the string
@Inject
CelebritySearchPage(@Named("search field") Lazy<TextField> searchField)
this.searchField = searchField;
文本字段
public class TextField
protected final Lazy<Page> page;
protected final String selector;
@Inject TextField(Lazy<Page> page, String selector)
this.page = page;
this.selector = selector;
/*
Lazy::get()
Return the underlying value, computing the value if necessary. All calls to the same Lazy instance will return the same result.
*/
我想一个 Lazy 也应该足够了。
【讨论】:
我该如何构造CelebritySearchPage
,因为TextField
和CelebritySearchPage
在它们的构造函数中需要彼此。
不要构造。注入。
如何注射?你能展示一个使用页面而不构建它的例子吗?
说实话,阅读精美的手册。从这里开始:github.com/google/guice/wiki/Motivation
github.com/google/guice/wiki/…以上是关于打破 Dagger 中的循环依赖的主要内容,如果未能解决你的问题,请参考以下文章