-
Notifications
You must be signed in to change notification settings - Fork 442
Open
Description
I have tried to make module from Hive with Generic models. Created 'CacheModel' mixin like this:
mixin CacheModel {
String get id;
CacheModel fromDynamicJson(dynamic json);
Map<String, dynamic> toJson();
}
And a manager to registerAdapters like this:
final class HiveCacheManager extends CacheManager {
HiveCacheManager({super.path});
@override
Future<void> init({required List<CacheModel> cacheModels}) async {
final documentPath =
path ?? (await getApplicationDocumentsDirectory()).path;
Hive.defaultDirectory = documentPath;
for (final cacheModel in cacheModels) {
Hive.registerAdapter(
'${cacheModel.runtimeType}', cacheModel.fromDynamicJson);
}
}
@override
void remove() {
Hive.deleteAllBoxesFromDisk();
}
}
CacheManager is an abstract class and have a CacheOperation abstract class like this:
abstract class CacheOperation<T extends CacheModel> {
void add(T item);
void addAll(List<T> items);
void remove(String id);
void clear();
List<T> getAll();
T? get(String id);
T? getFirst();
}
I also have a HiveCacheOperation which extends CacheOperation of T Type like this:
final class HiveCacheOperation<T extends CacheModel> extends CacheOperation<T> {
HiveCacheOperation() {
_box = Hive.box<T>(name: T.toString());
}
late final Box<T> _box;
@override
void add(T item) {
_box.put(item.id, item);
}
@override
void addAll(List<T> items) {
_box.putAll(Map.fromIterable(
items,
key: (element) => (element as T).id,
value: (element) => (element as T),
));
}
@override
void clear() {
_box.clear();
}
@override
T? get(String id) {
return _box.get(id);
}
@override
T? getFirst() {
return _box.get(_box.keys.first);
}
bool countBoxKeys() {
if (_box.isOpen) {
final count = _box.getAll(_box.keys).cast<T>().isNotEmpty;
return count;
}
return false;
}
@override
List<T> getAll() {
return _box
.getAll(_box.keys)
.where((element) => element != null)
.cast<T>()
.toList();
}
@override
void remove(String id) {
_box.delete(id);
}
}
I created a UserCacheModel and extend it from CacheModel like this:
final class UserCacheModel with CacheModel {
UserCacheModel({
required this.user,
});
UserCacheModel.empty() : user = const UserModel();
final UserModel user;
@override
CacheModel fromDynamicJson(json) {
final mapCast = json as Map<String, dynamic>?;
if (mapCast == null) return this;
return copyWith(userModel: UserModel.fromJson(mapCast));
}
@override
String get id => user.id.toString();
@override
Map<String, dynamic> toJson() {
return user.toJson();
}
UserCacheModel copyWith({UserModel? userModel}) {
return UserCacheModel(user: userModel ?? user);
}
}
Finally created a ProductCache which required CacheManager like this:
final class ProductCache {
ProductCache({required CacheManager cacheManager})
: _cacheManager = cacheManager;
final CacheManager _cacheManager;
Future<void> init() async {
await _cacheManager.init(
cacheModels: [
CorporationCacheModel(corporation: const CorporationModel()),
UserCacheModel(user: const UserModel()),
],
);
}
late final HiveCacheOperation<UserCacheModel> userCacheOperation =
HiveCacheOperation<UserCacheModel>();
late final HiveCacheOperation<CorporationCacheModel>
corporationCacheOperation = HiveCacheOperation<CorporationCacheModel>();
}
But when i try to call .getAll function of userCacheOperation i got "Invalid argument(s): Type mismatch. Expected UserCacheModel but got CorporationCacheModel.".
So is this a registerAdapter error or something else?
Metadata
Metadata
Assignees
Labels
No labels