Skip to content

Instantly share code, notes, and snippets.

@eccyan
Last active August 29, 2015 14:18
Show Gist options
  • Save eccyan/3bbac6acc28df2964210 to your computer and use it in GitHub Desktop.
Save eccyan/3bbac6acc28df2964210 to your computer and use it in GitHub Desktop.
俺的 Dagger ベストプラクティス ref: http://qiita.com/eccyan/items/434349e112efac4dee52
[root: ApplicationModule] >[injects: Application.java]
 └──<[includes: AwesomeModule]
     └──>[injects: LoginActivity.java]
     └──>[injects: ListActivity.java]
     └──>[injects: DetailActivity.java]
@Module(
includes = AwesomeModule.class,
library = true
)
public class ApplicationModule {
...
}
@Module(complete = false, library = true)
public class ApiModule.java {
@Provides @Singleton
public VideoDao provideYourService(RestAdapter adapter) { ... }
}
public class AwesomeActivity extends Activity {
@Inject
VideoDao mVideoDao;
@Inject
UserDao mUserDao;
...
}
@Module(
injects = AwesomeActivity.class,
includes = ApiModule.class
)
public class DaoModule {
@Provides @Singleton
public VideoDao provideVideoDao(YourService service) { ... }
@Provides @Singleton
public VideoDao provideUserDao(YourService service) { ... }
}
+ @Singleton
public class final VideoDao {
final YourService mService;
+ @Inject
public VideoDao(YourService service) { mService = service; }
public Observable<VideoModel> get(int id) {
return service.getVideo(id).first();
}
}
+ @Singleton
public class final UserDao {
final YourService mService;
+ @Inject
public UserDao(YourService service) { mService = service; }
public Observable<UserModel> get(int id) {
return service.getUser(id).first();
}
}
// Application Module
@Module(
includes = ApiModule.class,
injects = YourApplication.class
)
public class ApplicationModule {
...
}
// Awesome domain Module
@Module(
injects = AwesomeActivity.class,
addsTo = ApplicationModule.class,
library = true
)
public class AwesomeModule {
}
class MainPresenter {
@Inject Provider<ChildPresenter> mChildProvider;
private final List<ChildPresenter> mChilds = new ArrayList<>();
public void OnViewInflated() {
// Has 5 childs
for (int i=0; i < childCount; i++) {
final ChildPresenter presenter = mChildProvider.get();
((ChildView) getView().getChildAt(i)).setPresenter(presenter);
mChilds.add(presenter);
}
}
public void fireChildEvent(int id) {
mChilds.get(id).fire();
}
}
class ChildPresenter {
public void fire() { ... }
}
class ChildView extend View {
private ChildPresenter mPresenter;
public void setPresenter(ChildPresenter presenter) { mPresenter = presenter; }
}
class MainPresenter { 
public void fireChildEvent(int id) {
((ChildView) getView().getChildAt(id)).getPresenter().fire();
}
}
class ChildPresenter {
public void fire() { ... }
}
class ChildView extend View {
@Inject
Lazy<ChildPresenter> mPresenter;
public ChildPresenter getPresenter() { return mPresenter.get(); }
}
@Module(
injects = {
LoginActivity.class,
ListActivity.class,
DetailActivity.class
},
library = true
)
public class AwesomeModule {
...
}
public class AwesomeFragment extends Fragment {
final ObjectGraph mObjectGraph;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mObjectGraph = MainApplication.get(getActivity()).getObjectGraph()
.plus(getDaggerModule());
mObjectGraph.inject(this);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.awesome_fragment,
container, false);
mObjectGraph.inject(view.findViewById(R.layout.awesome_view));
return view;
}
...
}
public class AwesomeView extends FrameLayout {
static public class Factory implements LayoutInflater.Factory {
final ObjectGraph mObjectGraph;
public Factory(ObjectGraph objectGraph) { mObjectGraph = objectGraph; }
@Override
public View onCreateView(String name, Context context, AttributeSet attrs) {
// null を返すと標準のファクトリを使うので、型名で判定する。
if (!name.equalsIgnoreCase(AwesomeView.class.getName())) {
return null;
}
return new AwesomeView(context, attrs, mObjectGraph);
}
public AwesomeView(Context context, AttributeSet attrs, ObjectGraph objectGraph) {
objectGraph.inject(this);
}
...
}
public class AwesomeFragment extends Fragment {
final ObjectGraph mObjectGraph;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mObjectGraph = MainApplication.get(getActivity()).getObjectGraph()
.plus(getDaggerModule());
mObjectGraph.inject(this);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final LayoutInflater daggerInflater = inflater.cloneInContext(getActivity);
daggerInflater.setFactory(new AwesomeView.Factory(mObjectGraph));
final View view = inflater.inflate(R.layout.awesome_fragment,
container, false);
return view;
}
...
}
[root: ApplicationModule] >[injects: Application.java]
 ├──<[addsTo: LoginModule]
 │   └──>[injects: LoginActivity.java]
 ├──<[addsTo: ListModule]
 │   └──>[injects: ListActivity.java]
 └──<[addsTo: DetailModule]
     └──>[injects: DetailActivity.java]
@Module(
includes = AwesomeModule.class,
library = true
)
public class ApplicationModule {
...
}
@Module(
injects = LoginActivity.class,
addsTo = ApplicationModule.class,
library = true
)
public class LoginModule {
...
}
@Module(
injects = ListActivity.class,
addsTo = ApplicationModule.class,
library = true
)
public class ListModule {
...
}
@Module(
injects = DetailActivity.class,
addsTo = ApplicationModule.class,
library = true
)
public class DetailModule {
...
}
// Retrofit interface
interface YourService {
getVideo(int id);
getUser(int id);
}
public class final VideoDao {
final YourService mService;
public VideoDao(YourService service) { mService = service; }
public Observable<VideoModel> get(int id) {
return service.getVideo(id).first();
}
}
public class final UserDao {
final YourService mService;
public UserDao(YourService service) { mService = service; }
public Observable<VideoModel> get(int id) {
return service.getUser(id).first();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment