Comments (8)
First of all, @letsar has created this package, I have taken over the maintenance since 2 weeks. So all the credits go to him.
For your question:
Floor has a floor_generator that generates the non abstract class. If you want to register the abstract class you will have to register an instance that comes from the generated database.
Personally, I have never used floor but by reading the readme on pub.dev I think that is the way to go.
I use moor because it generates the dao classes in a separate file and the dao needs a database. So that will be injected with kiwi as well.
I will have some spare time on Thursday so I will play around with Floor and I will let you know what the best sollution is.
from kiwi.
@vanlooverenkoen Thanks, It's okay to use Repository class as a singleton? because repository class contains objects which provides access to API and Database. So, by making Repository class singleton, we will be using a repository and related API and DB as a singleton too. Do I understood this part correct? kindly express your views on it.
from kiwi.
Yes indeed. We usually do it like this
Singleton repo's
Singleton services (apis)
Singleton dao's
Singleton database
Factories viewmodels
On top of that every Singleton ia registered as an abstract class. So it is easier to write automated tests
from kiwi.
@vanlooverenkoen So, Database class and Dao's in floor are implemented as abstract class only? so does that mean it's singleton by default?
from kiwi.
No that does not mean it is a singleton by default. (Im not sure what the correct implementation is for floor. But I would think it is just a normal object. By using kiwi you can make sure the instance is always a singleton. Because kiwi maintains that for you.
from kiwi.
@vanlooverenkoen Kindly let me know if there's any way to do it using abstract class, I did't have any example for it. A big thanks in advance.
from kiwi.
Hello @vanlooverenkoen, I have give your advice a shot and look into generated floor file, which is as below.
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'cookdb.dart';
// **************************************************************************
// FloorGenerator
// **************************************************************************
class $FloorCookDataBase {
/// Creates a database builder for a persistent database.
/// Once a database is built, you should keep a reference to it and re-use it.
**static _$CookDataBaseBuilder databaseBuilder(String name) =>
_$CookDataBaseBuilder(name);**
/// Creates a database builder for an in memory database.
/// Information stored in an in memory database disappears when the process is killed.
/// Once a database is built, you should keep a reference to it and re-use it.
static _$CookDataBaseBuilder inMemoryDatabaseBuilder() =>
_$CookDataBaseBuilder(null);
}
class _$CookDataBaseBuilder {
_$CookDataBaseBuilder(this.name);
final String name;
final List<Migration> _migrations = [];
Callback _callback;
/// Adds migrations to the builder.
_$CookDataBaseBuilder addMigrations(List<Migration> migrations) {
_migrations.addAll(migrations);
return this;
}
/// Adds a database [Callback] to the builder.
_$CookDataBaseBuilder addCallback(Callback callback) {
_callback = callback;
return this;
}
/// Creates the database and initializes it.
Future<CookDataBase> build() async {
final path = name != null
? await sqfliteDatabaseFactory.getDatabasePath(name)
: ':memory:';
final database = _$CookDataBase();
database.database = await database.open(
path,
_migrations,
_callback,
);
return database;
}
}
class _$CookDataBase extends CookDataBase {
_$CookDataBase([StreamController<String> listener]) {
changeListener = listener ?? StreamController<String>.broadcast();
}
CookDAO _cookDAOInstance;
Future<sqflite.Database> open(String path, List<Migration> migrations,
[Callback callback]) async {
final databaseOptions = sqflite.OpenDatabaseOptions(
version: 1,
onConfigure: (database) async {
await database.execute('PRAGMA foreign_keys = ON');
},
onOpen: (database) async {
await callback?.onOpen?.call(database);
},
onUpgrade: (database, startVersion, endVersion) async {
await MigrationAdapter.runMigrations(
database, startVersion, endVersion, migrations);
await callback?.onUpgrade?.call(database, startVersion, endVersion);
},
onCreate: (database, version) async {
await database.execute(
'CREATE TABLE IF NOT EXISTS `Cook` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `cookName` TEXT, `gender` TEXT, `experience` INTEGER, `language` TEXT, `perMonthCharge` INTEGER, `rating` REAL)');
await callback?.onCreate?.call(database, version);
},
);
return sqfliteDatabaseFactory.openDatabase(path, options: databaseOptions);
}
@override
CookDAO get cookDAO {
return _cookDAOInstance ??= _$CookDAO(database, changeListener);
}
}
class _$CookDAO extends CookDAO {
_$CookDAO(this.database, this.changeListener)
: _queryAdapter = QueryAdapter(database),
_cookInsertionAdapter = InsertionAdapter(
database,
'Cook',
(Cook item) => <String, dynamic>{
'id': item.id,
'cookName': item.cookName,
'gender': item.gender,
'experience': item.experience,
'language': item.language,
'perMonthCharge': item.perMonthCharge,
'rating': item.rating
});
final sqflite.DatabaseExecutor database;
final StreamController<String> changeListener;
final QueryAdapter _queryAdapter;
static final _cookMapper = (Map<String, dynamic> row) => Cook(
row['id'] as int,
row['cookName'] as String,
row['gender'] as String,
row['experience'] as int,
row['language'] as String,
row['perMonthCharge'] as int,
row['rating'] as double);
final InsertionAdapter<Cook> _cookInsertionAdapter;
@override
Future<List<Cook>> fetchAllCooks() async {
return _queryAdapter.queryList('Select * from Cook', mapper: _cookMapper);
}
@override
Future<void> insertCooks(List<Cook> cook) async {
await _cookInsertionAdapter.insertList(cook, OnConflictStrategy.replace);
}
}
Now in my main function, I have create singleton Object by following.
main(List<String> args) {
KiwiContainer kiwiContainer = KiwiContainer();
kiwiContainer.registerSingleton((container) => Repository());
kiwiContainer.registerSingleton((container) => APIProvider());
**kiwiContainer.registerSingleton((container) async {
return await $FloorCookDataBase.databaseBuilder('cook_db.db').build();
});
kiwiContainer.registerSingleton((container)=>KiwiContainer().resolve<CookDataBase>().cookDAO);**
runApp(MainPage());
}
@vanlooverenkoen can you kindly tell me if my approach is right or not? I am accessing DataBase class through builder and using that singleton Database Object I am accessing DAO object which is defined as a class in CookDataBase abstract class. like following :
@Database(version: 1, entities: [Cook])
abstract class CookDataBase extends FloorDatabase {
CookDAO get cookDAO;
}
from kiwi.
@jaydangar I'm sorry that it took so long. I completely forgot about this ticket. I would do the following
Future<void> main(List<String> args) async{
await setupDi();
runApp(MainPage());
}
Future<void> setupDi(){
KiwiContainer().registerSingleton((container) => Repository());
KiwiContainer().registerSingleton((container) => APIProvider());
final db = await $FloorCookDataBase.databaseBuilder('cook_db.db').build()
KiwiContainer().registerSingleton((container) => db);
KiwiContainer().registerSingleton((container)=> KiwiContainer().resolve<CookDataBase>().cookDAO);
}
Using the kiwi_generator will result in some extra boilerplate code, that is because of how floor
is setup.
Your personDao
import 'package:floor/floor.dart';
import 'package:kiwi_floor/db/database.dart';
import 'package:kiwi_floor/models/person.dart';
@dao
abstract class PersonDao {
factory PersonDao.fromDb(AppDatabase db) => db.personDao; //the extra boilerplate code
@Query('SELECT * FROM Person')
Future<List<Person>> findAllPersons();
@Query('SELECT * FROM Person WHERE id = :id')
Stream<Person> findPersonById(int id);
@insert
Future<void> insertPerson(Person person);
}
And your injector file will look like this:
abstract class Injector {
Future<void> configure() async {
final db = await $FloorCookDataBase.databaseBuilder('cook_db.db').build()
KiwiContainer().registerSingleton((container) => db);
registerDao();
}
@Register.singleton(PersonDao, constructorName: 'fromDb') //consturctorName is extra boilerplate code to use with floor
void registerDao();
}
I personally use Moor for my db integration. It works way better with kiwi. Because the implementation of moor is better for dependency injection.
I hope this answers your question. Sorry for the late response.
from kiwi.
Related Issues (20)
- between kiwi and flutter_test version solving failed. issue HOT 2
- Add no response bot
- Null Safety HOT 1
- How can I create scoped container? HOT 2
- Generate custom Stateless widget and State HOT 1
- The type `Object` was not registered HOT 1
- Can I create `kiwi_generator` record for a string? HOT 7
- Use cascade operator in generated code HOT 3
- Doesn't work with build_runner 2.0.4 HOT 6
- Update analyzer ^1.7.1 to analyzer ^2.0.0 HOT 3
- Can't use try/catch with kiwi
- Class could not be registered correctly even when defaults are specified
- Code generator does not play nice with mockito HOT 1
- Kiwi injection not working in background/app killed state. HOT 4
- Allow analyzer version 4.x. HOT 1
- migrate to github actions HOT 1
- It is not generating anything HOT 1
- kiwi_generator cannot be used with newer analyzers HOT 8
- Please add docs which example is "compile-time DI" HOT 1
- Add possibility to resolve collection of types by super type
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from kiwi.