Skip to content

[Feature]: Using @WithCache on a class that already extends another abstract class #126

@edwinquaihoi

Description

@edwinquaihoi

Problem

Hi great library but I have a use case that I can't seem to get working. I have a bunch of service classes that extend an existing abstract class. The abstract has some default behaviours for methods that need to be inherited to sub classes.

abstract class AbstractSvc<E extends BaseEntity, R extends AbstractRepo> {
  
  R repo;

  AbstractSvc({required this.repo});

  E Function(Map<String, dynamic>) converter();
  
  // default implementation
  Future<E> read(String id) async {
    return repo.findById(id, converter());
  }
}

An implementation of this abstract class might look like this, here I am overriding a method from the AbstractSvc to make it cached in the sub class. Note I also use GetIt and Injectable with Injectable _Generator libraries to implement dependency injection (Service Locator pattern) of services and repositories.

@LazySingleton()
class ValuelistSvc extends AbstractSvc<Valuelist, ValuelistRepo>{
  
  ValuelistSvc({required super.repo});
  
  @override
  Valuelist Function(Map<String, dynamic>) converter() {
    return Valuelist.fromJson;
  }
 
  @Cached()
  @override
  Future<Valuelist> read(String id) async {
    return repo.findById(id, converter());
  }
}

After adding @WithCache to the implementation the generated class is invalid as with the error 'The class 'ValuelistSvc' can't be used as a mixin because it extends a class other than 'Object''

part of 'ValuelistSvc.dart';

// **************************************************************************
// CachedGenerator
// **************************************************************************

abstract class _$ValuelistSvc {
  ValuelistRepo get repo;
}

class _ValuelistSvc with ValuelistSvc implements _$ValuelistSvc {
  _ValuelistSvc({required this.repo});

  @override
  final ValuelistRepo repo;

  final _readCached = <String, Valuelist>{};

  @override
  Future<Valuelist> read(String id) async {
    final cachedValue = _readCached["${id.hashCode}"];
    if (cachedValue == null) {
      final Valuelist toReturn;
      try {
        final result = super.read(id);

        toReturn = await result;
      } catch (_) {
        rethrow;
      } finally {}

      _readCached["${id.hashCode}"] = toReturn;

      return toReturn;
    } else {
      return cachedValue;
    }
  }
}

Desired Solution

Is using @WithCache on a class which extends an abstract class supported? If not do you have any work arounds to resolve the issue. I don't want to have to add a bunch of service interfaces and then have to cut and paste default implementations of crud methods everywhere.

Alternatives Considered

You library is very similar to the ts-method-cache lib in NPM, would be great if we could get it to work in a similar manner without forcing a specific inheritance style. The other option I have is to implement Dio Http Interceptors.

On which platorm do you expect this solution?

All

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions