Home > Enterprise >  How can I create a class with factory method and use it as singleton?
How can I create a class with factory method and use it as singleton?

Time:01-30

I tried creating a class that has a factory method and use it as a singleton class . However my class needs a few constructors and doing so I always fail to write it properly

Is it possible to pass constructor and use a factory method ? I have not been able to do so. this is the class

class LocationService {
  BuildContext context;
  late Position position;
  GeoPoint? initPosition;
  bool loadGeoFire = false;
  Function update_drivers;
  bool nearbyAvailableDriverKeysLoaded;
  bool removeDriverIcon;
  String? removeDriverKey;

  LocationService({
    required this.context,
    required this.update_drivers,
    required this.nearbyAvailableDriverKeysLoaded,
    required this.removeDriverIcon,
    required this.removeDriverKey,
    required this.initPosition,
    required this.loadGeoFire,
    // required this.position,
  });

  Future<void> locatePosition() async {
    final appData = context.read<AppData>();
    position = await Geolocator.getCurrentPosition(
        desiredAccuracy: LocationAccuracy.high);
    print("This is your Position:: "   position.toString());

    GeoPoint initPos =
        GeoPoint(latitude: position.latitude, longitude: position.longitude);

    initPosition = initPos;

    appData.initPosition = initPos;
    String address =
        // ignore: unnecessary_cast
        await (AssistantMethods.searchCoordinateAddress(position, context)
            as FutureOr<String>);
    print("This is your Address:: "   address);
    if (!loadGeoFire) {
      initializeGeoFire(
        position: position,
        update_drivers: update_drivers,
        nearbyAvailableDriverKeysLoaded: nearbyAvailableDriverKeysLoaded,
        removeDriverIcon: removeDriverIcon,
        removeDriverKey: removeDriverKey,
      );
      loadGeoFire = true;
    }
    // uName = userCurrentInfo.name;
    Provider.of<AppData>(context, listen: false).closeSplashScreen(false, true);
    AssistantMethods.retrieveHistoryInfo(context);
  }
}

I tried to do sth like this

class LocationService {
  BuildContext context;
  late Position position;
  GeoPoint? initPosition;
  bool loadGeoFire = false;
  Function update_drivers;
  bool nearbyAvailableDriverKeysLoaded;
  bool removeDriverIcon;
  String? removeDriverKey;

  static final LocationService _instance = LocationService._internal(
    context: context,
    update_drivers: update_drivers,
    nearbyAvailableDriverKeysLoaded: nearbyAvailableDriverKeysLoaded,
    removeDriverIcon: removeDriverIcon,
    removeDriverKey: removeDriverKey,
    initPosition: initPosition,
    loadGeoFire: loadGeoFire,
    position: position,
  );

  factory LocationService() {
    return _instance;
  }

  LocationService._internal({
    required this.context,
    required this.update_drivers,
    required this.nearbyAvailableDriverKeysLoaded,
    required this.removeDriverIcon,
    required this.removeDriverKey,
    required this.initPosition,
    required this.loadGeoFire,
    required this.position,
  });

won't work though. keep getting the error The instance member 'context' can't be accessed in an initializer. Try replacing the reference to the instance member .. etc Also do I really need to create a singleton class ? I am callinglocatePosition method from different places, read it was a good practice and want to do so.

This is how i call it from another class

 @override
  Future<void> mapIsReady(bool isReady) async {
 
     
      LocationService locationService = LocationService(
        context: context,
        update_drivers: update_drivers,
        nearbyAvailableDriverKeysLoaded: nearbyAvailableDriverKeysLoaded,
        removeDriverIcon: removeDriverIcon,
        removeDriverKey: removeDriverKey,
        initPosition: initPosition,
        loadGeoFire: loadGeoFire,
      );

// calling the locatePosition method
      await locationService.locatePosition();
    }
  }

CodePudding user response:

It's for sure possible to pass arguments even when using a singleton constructor in Dart.

Here I have added positional parameters in the constructor but you can add named parameters too in it.

Here's the example for it:

class LocationService {
  late BuildContext context;
  late Position position;
  late GeoPoint? initPosition;
  late bool loadGeoFire = false;
  late Function update_drivers;
  late bool nearbyAvailableDriverKeysLoaded;
  late bool removeDriverIcon;
  late String? removeDriverKey;

  static final LocationService _instance = LocationService._internal();
  LocationService._internal();

  factory LocationService(
    BuildContext context,
    Function update_drivers,
    bool nearbyAvailableDriverKeysLoaded,
    bool removeDriverIcon,
    String removeDriverKey,
    GeoPoint initPosition,
    bool loadGeoFire,
    Position position,
  ) {
    _instance.context = context;
    _instance.update_drivers = update_drivers;
    _instance.nearbyAvailableDriverKeysLoaded = nearbyAvailableDriverKeysLoaded;
    _instance.removeDriverIcon = removeDriverIcon;
    _instance.removeDriverKey = removeDriverKey;
    _instance.initPosition = initPosition;
    _instance.loadGeoFire = loadGeoFire;
    _instance.position = position;
    return _instance;
  }
}

CodePudding user response:

I did it this way tho

class LocationService {
  static LocationService? _locationService;

  final BuildContext context;
  final Function update_drivers;
  final bool nearbyAvailableDriverKeysLoaded;
  final bool removeDriverIcon;
  final String? removeDriverKey;
  GeoPoint? initPosition;
  bool loadGeoFire;



  late Position position;

  LocationService._({
    required this.context,
    required this.update_drivers,
    required this.nearbyAvailableDriverKeysLoaded,
    required this.removeDriverIcon,
    required this.removeDriverKey,
    required this.initPosition,
    required this.loadGeoFire,
  });

  factory LocationService({
    required BuildContext context,
    required Function update_drivers,
    required bool nearbyAvailableDriverKeysLoaded,
    required bool removeDriverIcon,
    required String? removeDriverKey,
    required GeoPoint? initPosition,
    required bool loadGeoFire,
  }) {
    _locationService ??= LocationService._(
      context: context,
      update_drivers: update_drivers,
      nearbyAvailableDriverKeysLoaded: nearbyAvailableDriverKeysLoaded,
      removeDriverIcon: removeDriverIcon,
      removeDriverKey: removeDriverKey,
      initPosition: initPosition,
      loadGeoFire: loadGeoFire,
    );
    return _locationService!;
  }
  • Related