Использование Dagger с вложенными фрагментами и представлениями

Я все еще пытаюсь понять кинжальное мышление внедрения зависимостей и сталкиваюсь с некоторыми проблемами. У меня есть MyNavBar, который представляет собой представление во фрагменте. Я не могу понять, как внедрить в него класс MainWrapper моего приложения. Вот как устроен мой код:

У меня есть MainActivity в модуле Android моего приложения:

public class MainActivity extends Activity {

    private MainWrapper mainWrapper;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    //Create the basic interface which will have parts swapped out with
    // fragments in MainWrapper:
    this.setContentView(R.layout.main);

    ObjectGraph graph = ObjectGraph.create(new MyDaggerModule(this));
    this.mainWrapper = new MainWrapper(graph);
}

Затем в библиотеке существует MainWrapper, который содержит почти весь код моего приложения:

public class MainWrapper {

    @Inject
    protected MenuFragment menu;
    @Inject
    protected Activity activity;
    private ObjectGraph objGraph;

    public MainWrapper(ObjectGraph objGraph) {
        this.objGraph = objGraph;
        this.objGraph.inject(this); //populated this.menu and this.activity

        Fragment mainFragment = new MainFragment();
        this.objGraph.inject(mainFragment);

        //Transaction to swap out blank fragment for mainFragment
        // ...
    }
}

MainFragment — довольно стандартный фрагмент:

public class MainFragment extends Fragment {

    protected MyNavBar navBar; //LinearLayout

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View mainContentView = inflater.inflate(R.layout.main_content, container, false);

        this.navBar = (MyNavBar) mainContentView.findViewById(R.id.main_nav_bar);

        return mainContentView;
    }
}

Наконец, вот фрагмент MyNavBar:

public class MyNavBar extends UILinearLayout {
    @Inject
    protected MainWrapper wrapper;
    protected View menuButton;

    //Constructors that call init() at the end
    // ...

    protected void init() {
        this.setContentView(R.layout.navbar);
        this.menuButton = this.findViewById(R.id.menuBtn);
        this.menuButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                //I want to call methods on MainWrapper here.
            }
        });
    }
}

Как я могу заставить MainWrapper внедрить оболочку в этот класс MyNavBar, используя DI? Я понимаю, что могу внедрить MainWrapper в MainFragment, а затем создать сеттер в MyNavBar, но это, похоже, в первую очередь противоречит цели DI.

Я предполагаю, что в конечном итоге я спрашиваю следующее: если у вас есть основная активность, которая создает фрагмент, и у этого фрагмента есть представления, как вы можете внедрять представления этих фрагментов, сохраняя при этом ObjectGraph только в основном действии? В какой-то момент вам не придется вызывать objectGraph.inject() для представлений фрагмента?


person John D.    schedule 21.01.2015    source источник
comment
Пожалуйста, можете выложить трассировку стека?   -  person Emmanuel    schedule 22.01.2015
comment
Нет трассировки стека, проблема в том, что MainWrapper в MyNavBar равен нулю.   -  person John D.    schedule 22.01.2015
comment
onCreateView будет вызываться только тогда, когда фрагмент прикреплен к активности. Так что во время вашей инъекции MyNavBar вообще не существует   -  person Eugen Martynov    schedule 22.01.2015
comment
Да, я только что это понял. У меня есть вещи, работающие с использованием сеттеров на MyNavBar, поэтому я продолжаю. Кажется неэлегантным, но эй, это лучше, чем не работать. Также можно рассмотреть возможность интеграции Butterknife.   -  person John D.    schedule 22.01.2015