패키지, 저장소 및 앱 카테고리 검색

패키지 상세v2.0.0

toor

컴파일 시 안전하고 관리하기 쉬운 서비스 로케이터입니다.

AndroidiOSWebmacOSWindowsLinux
30일 다운로드
867
좋아요
9
Pub 점수
150

패키지 설치

flutter pub add toor

패키지 개요

공개 정보를 바탕으로 생성한 선택 가이드입니다.

Toor는 Flutter 및 Dart 애플리케이션을 위한 컴파일 시 안전한 서비스 로케이터로, 최소한의 부가 코드로 종속성 주입을 간편하게 만듭니다. 타입 안전한 API를 사용하여 서비스를 등록하고 검색할 수 있어 오류를 런타임이 아닌 컴파일 시점에 잡을 수 있습니다. 모든 주요 플랫폼을 지원하며 코드 유지보수성을 향상시키고 잘못된 종속성 설정의 위험을 줄입니다. 가벼운 설계로 기존 프로젝트에 복잡한 설정이나 어노테이션 없이 쉽게 통합됩니다.

사용 사례

  • 애플리케이션 전반의 종속성 관리
  • 수동 서비스 인스턴스화 대체
  • 테스트 가능하고 모듈화된 코드 활성화
  • 대규모 앱에서 종속성 주입 간소화
  • 클린 아키텍처 패턴 촉진

주요 기능

  • 컴파일 시 안전성
  • 최소한의 보일러플레이트
  • 형 안전한 서비스 해결
  • 크로스 플랫폼 지원
  • 기존 코드베이스와의 간편한 통합
  • 주석이나 코드 생성이 필요 없음

적합한 대상

  • 간단한 DI 솔루션을 찾는 개발자
  • 높은 신뢰성과 조기 오류 탐지를 요구하는 프로젝트
  • 클린 아키텍처를 채택하는 팀
  • 다중 플랫폼 대상 애플리케이션
  • 대규모 Flutter 앱 유지보수

고려 사항

  • 기존 종속성 사용에 대한 초기 리팩터링이 필요할 수 있습니다
  • 완전한 DI 프레임워크에 비해 고급 기능이 제한됨
  • 복잡한 종속성 요구 사항을 가진 중대형 프로젝트에 가장 적합
  • 의존성이 적은 매우 작은 앱에는 적합하지 않습니다

원본 README

연결된 소스 저장소의 README 원문 스냅샷입니다. 최신 내용은 저장소에서 확인하세요.

codecov Pub version GitHub stars

🌱 What is Toor

Toor makes service locators compile-time safe and easy to manage.

Table of Contents

🚀 Getting Started

Define your dependencies somewhere in the project. All global and static variables are lazy by default so you shouldn't worry about consuming memory that's not used by registering stuff.

final toor = Toor.instance;

final httpClientSingleton = toor.registerLazySingleton<IHttpClient>(
  DioHttpClientImpl.new,
);

final authRepositoryFactory = toor.registerFactory<IAuthRepository>(
  () => AuthRepositoryImpl(httpClient: httpClientSingleton()),
);

After that, you can safely access your registered factories or lazy singletons:

void authenticate(String email, String password) {
  authRepositoryFactory().authenticate(email, password);
}

✨ Toor in detail

Types of locators

Toor currently supports two types of objects: factories and lazy singletons.

Factory

Factories are locators that are created on each time you get them.

Use Toor.registerFactory to create factory locators:

final toor = Toor.instance;

final authRepositoryFactory = toor.registerFactory<IAuthRepository>(
  AuthRepositoryImpl.new,
);
Lazy Singleton

Lazy singletons are locators that are created only on the first call. The object, created at the first call, will be returned every time you get it afterwards.

Use Toor.registerLazySingleton to create lazy singleton locators:

final toor = Toor.instance;

final credentialManager = toor.registerLazySingleton<ICredentialManager>(
  CredentialManagerImpl.new,
);
Mutable Lazy Singleton

In some cases you may need your singletons to be mutable (e. g. flavors). Toor has mutable singletons for that. Use Toor.registerMutableLazySingleton in order to create a lazy singleton with a mutable value. And, in order to change the value of the singleton, use put:

final toor = Toor.instance;

final appFlavor = toor.registerMutableLazySingleton(
  create: () => Flavor.dev,
);
print(appFlavor()); // Flavor.dev

appFlavor.put(Flavor.prod);

print(appFlavor()); // Flavor.prod

When calling reset on mutable singletons, the original value (from create) is assigned to them.

Additional cleanup code with onDispose

Toor allows you to pass an optional onDispose function when registering lazy singletons in order to do some clean-up (e.g. close a socket connection, unsubscribe from a stream etc). onDispose also gives you access to the current value of the singleton. In order to use it, just pass the onDispose argument when calling registerLazySingleton:

final toor = Toor.instance;

final permissionManager = toor.registerLazySingleton<IPermissionManager>(
  PermissionManagerImpl.new,
  onDispose: (manager) {
    manager.dispose();
  },
);
Async Factory

Async factories are locators that are asynchronously created each time you get them.

Use Toor.registerFactoryAsync to create async factory locators:

final toor = Toor.instance;

final dataPersisterFactory = toor.registerFactoryAsync<IDataPersister>(
  () async => SharedPreferencesDataPersister(
    sharedPreferences: await SharedPreferences.getInstance(),
  ),
);

Await the creation of your factory to obtain and use it:

final dataPersister = await dataPersisterFactory();
dataPersister.saveData('big');
Factories with parameters

You can also create factories that accept 1 or 2 parameters:

final toor = Toor.instance;

final personFactory = toor.registerFactoryWithParam<Person, String>(
  (name) => Person(name),
);

final vehicleFactory = toor.registerFactoryWithTwoParams<Vehicle, String, int>(
  (name, productionYear) => Vehicle(name, productionYear);
);

class Person {
  const Person(this.name);

  final String name;
}

class Vehicle {
  const Vehicle(this.name, this.productionYear);

  final String name;
  final int productionYear;
}

void main() {
  // Both are compile-time safe and know about the types.
  final driver = personFactory('Doc');
  final vehicle = vehicleFactory('DeLorean', 1981);
}

Async factories are also supported via registerFactoryAsyncWithParam and registerFactoryAsyncWithTwoParams.

Advanced usage
Resetting lazy singletons

You can reset lazy singletons via the reset method. This will delete the current object and create a new one on the next call.

final toor = Toor.instance;

String value = 'Initial';

final lazySingleton = toor.registerLazySingleton<String>(
  () => value,
);

// Even though we change the `value` variable here,
// `lazySingleton`s value will remain 'Initial'.
value = 'Changed';

print(lazySingleton()); // 'Initial'

// Once we reset `lazySingleton`, it's value will be 'Changed' on the next call.
lazySingleton.reset();

print(lazySingleton()); // 'Changed'
Resetting all lazy singletons

Toor lets you reset all lazy singletons at once via the reset method on its instance. This will call reset on every lazy singleton, registered with it.

final toor = Toor.instance;

String value = 'Initial';

final lazySingleton = toor.registerLazySingleton<String>(
  () => value,
);

value = 'Changed';

print(lazySingleton()); // 'Initial'

// Once we reset `toor`, all lazy singletons, registered via
// `toor.registerLazySingleton` will be reset.
toor.reset();

print(lazySingleton()); // 'Changed'
Creating new instances of Toor

You may want to create several instances of Toor, independent of each other. The Toor.instance getter will return the default instance but you don't have to use it. You can create new instances of Toor via Toor.newInstance(). You may want to do this in order to reset lazy singletons, related to a single domain (e.g. reset all singletons that hold user data on logout).

final authToor = Toor.newInstance();
final analyticsToor = Toor.newInstance();

final credentialManager = authToor.registerLazySingleton<ICredentialManager>(
  CredentialManagerImpl.new,
);

final sessionRecorder = authToor.registerLazySingleton<ISessionRecorder>(
  SessionRecorderImpl(upload: false),
);

void logout() {
  // `credentialManager` will be reset, however `sessionRecorder` won't, since
  // it's registered in `analyticsToor`, not `authToor`.
  authToor.reset();
}
Registering locators with top-level functions

Toor provides several ways to register a locator in the global toor instance:

// You can use `Toor.instance` getter and then call 
// `registerLazySingleton` or any other method on it.
final toor = Toor.instance;

final httpClientSingleton = toor.registerLazySingleton<IHttpClient>(
  DioHttpClientImpl.new,
);

// Or you can use a top-level function with the same name 
// which basically will call the method on `Toor.instance`.
final httpClientSingleton = registerLazySingleton<IHttpClient>(
  DioHttpClientImpl.new,
);

🧪 Testing with Toor

Sometimes, you need different (e.g. mock) objects to be created in tests. There are two ways to achieve that with Toor:

  1. Deciding what to register based on some variables / other toor singletons (e. g. flavor):
final toor = Toor.instance;

final authManager = toor.registerLazySingleton<IAuthManager>(
  flavor.isTesting ? MockAuthManager() : AuthManagerImpl(),
);
  1. Overriding registered objects via override which is available in toor_test. The override method is annotated with visibleForTesting since it's intended to be used only in tests:
// dependencies.dart
import 'package:toor/toor.dart';

final toor = Toor.instance;

final authManager = toor.registerLazySingleton<IAuthManager>(
  AuthManagerImpl.new,
);
// app_test.dart
import 'package:toor/toor_test.dart';

void main() {
  setUpAll(() {
    authManager.override(() => MockAuthManager());
  });
}

카테고리

의존성

의존성 목록 1 개

소스 저장소

이 패키지를 사용하는 프로젝트

아직 데이터가 없습니다.