2015-07-23 3 views
4

Я очень новая для кинжала - я даже не знаю, если это будет работать для моего приложенияЛомать циклическую зависимость в 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"); 
    } 
} 

Page

public abstract class Page { 
    // ... 
} 

Text Field

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. Как мне преодолеть эту циклическую зависимость?

Я не могу инициализировать searchField внутри CelebritySearchPage

+0

Почему TextField нужна страница? –

+0

@AndreasFrische 'textField.getFullSelector()' вызывает 'page.getFullSelector()' – michaelsnowden

+1

ok. Может быть, тогда введет FullSelectorHolder. Или используйте «Lazy»: «Иногда вам нужен объект, создаваемый лениво. Для любой привязки T вы можете создать Lazy , который исправляет создание экземпляра до первого вызова метода get() Lazy . –

ответ

1

Рассмотрим это:

CelebritySearchPage

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; 
    } 
} 

Text Field

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. 
*/ 
} 

Я думаю, один Ленивый должен suffic e также.

+0

Как я тогда создаю 'CelebritySearchPage', потому что' TextField' и 'CelebritySearchPage' требуют друг друга в своем конструкторе. – michaelsnowden

+0

Не строите. Вводят. –

+0

Как мне впрыскивать? Можете ли вы показать пример использования страницы без ее создания? – michaelsnowden

Смежные вопросы