Я прочитал post Кристиана Грубера, и я начал задаваться вопросом, как использовать синглэты в приложении.
В моем приложении у меня есть класс DBHelper
, основной целью которого является сохранение ключей в моей базе данных. У меня также много (по крайней мере двух) разных DAO.
Теперь - я не вижу причины, почему мои несколько видов деятельности/классов должны быть больше, чем просто один экземпляр DAO. Более того, зачем DAO нужен экземпляр DBHelper
только для себя? Я уверен, что они могут поделиться, особенно я не предсказываю ситуации, когда оба DAO хотели бы выполнить некоторую операцию в моей базе данных одновременно. Итак, давайте посмотрим некоторые классы:Как использовать Singleton в Dagger 1.x?
DBHelper
@Singleton public class DBHelper extends SQLiteOpenHelper { //some not relevant configuration stuff private Context context; @Inject public DBHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); this.context = context; } @Override public void onCreate(SQLiteDatabase db) { //db.execSQL, creating tables and stuff } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { //dropping tables, creating a new one onCreate(db); } }
пример
DAO
public interface SomeDataDAO { void hai(); } public class SomeDataDAOImpl implements SomeDataDAO { private DBHelper dbHelper; public SomeDataDAOImpl(DBHelper dbHelper){ this.dbHelper = dbHelper; } @Override public void hai() { SQLiteDatabase database = dbHelper.getWritableDatabase(); dbHelper.doSomeDatabaseStuff() } }
SomeDataModule
@Module( injects = { MainActivity.class, SomeServiceImpl.class } ) public class SomeDataModule { private Context appContext; @Provides @Singleton public SomeDataDAO provideSomeDataDao(DBHelper dbHelper){ return new SomeDataDAOImpl(dbHelper); } @Provides @Singleton public ISomeService provideSomeService(SomeServiceImpl impl){ return impl; } @Provides public Context getAppContext(){ return this.appContext; } public SomeDataModule(){ this.appContext = MainActivity.getAppContext(); } }
Теперь давайте посмотрим два примера потребителей зависимостей
public class MainActivity extends ActionBarActivity { @Inject SomeDataDAO someDataDAO; private ObjectGraph objectGraph; @Inject ISomeService someService; private static Context appContext; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); appContext = getApplicationContext(); objectGraph = ObjectGraph.create(SomeDataModule.class); objectGraph.inject(this); someService.doSomeStuff(); } public static Context getAppContext() { return appContext; } }
public class SomeServiceImpl implements ISomeService { private ObjectGraph objectGraph; @Inject public SomeDataDAO someDataDAO; public SomeServiceImpl(){ objectGraph = ObjectGraph.create(GraphDataModule.class); objectGraph.inject(this); } public void doSomeStuff(){ someDataDAO.hai(); } }
Он работает, но когда я inject(this)
дважды, Dagger, очевидно, создает мне два экземпляра DBHelper
, как он считает, «Один синглтон с одним экземпляром графа». Как обернуть мой SomeDataModule
в ApplicationModule
, так что у меня есть только один экземпляр DBHelper
во всем приложении? Добавление @Singleton
к DBHelper
, к сожалению, было недостаточно.
Если вы должны пойти синглтон, почему бы не использовать Глобальный класс со статическими членами и методами? –
@KristyWelsh Я изучаю Android и кинжал. Даже если в этом конкретном случае класс со статическими элементами и методами может быть лучше, я хотел бы знать, как достичь своей цели с помощью инъекции зависимостей, особенно когда у меня есть довольно простой пример прямо сейчас. Кстати, это даже правильный шаблон дизайна? Я не думаю, что когда-либо сталкивался с таким подходом. Я встретил класс со статическими полями, давая константы, SQL и т. Д., Но никогда не распространяя DAO. – spoko