feat(arch): GetIt DI + IIAPService/IAdService 인터페이스 도입

- core/di/: service_locator, IIAPService, IAdService 생성
- IAPService/AdService: implements 인터페이스 + GetIt 위임
- main.dart: setupServiceLocator() 호출
- 기존 .instance getter 호환성 100% 유지
- test/helpers/test_setup.dart: 테스트용 서비스 로케이터 초기화
This commit is contained in:
JiWoong Sul
2026-03-30 19:41:13 +09:00
parent c382d6d770
commit e051bd451a
11 changed files with 150 additions and 15 deletions

View File

@@ -12,7 +12,10 @@ import 'package:pointycastle/asn1/primitives/asn1_bit_string.dart';
import 'package:pointycastle/asn1/primitives/asn1_integer.dart';
import 'package:pointycastle/asn1/primitives/asn1_sequence.dart';
import 'package:get_it/get_it.dart';
import 'package:asciineverdie/data/game_text_l10n.dart' as game_l10n;
import 'package:asciineverdie/src/core/di/i_iap_service.dart';
/// IAP 상품 ID
class IAPProductIds {
@@ -62,16 +65,14 @@ String get _googlePlayPublicKey => _gpKeyPart1 + _gpKeyPart2;
///
/// 인앱 구매 (광고 제거) 처리를 담당합니다.
/// flutter_secure_storage를 사용하여 구매 상태를 보안 저장합니다.
class IAPService {
class IAPService implements IIAPService {
IAPService._();
static IAPService? _instance;
/// GetIt 등록용 팩토리 메서드
factory IAPService.createInstance() => IAPService._();
/// 싱글톤 인스턴스
static IAPService get instance {
_instance ??= IAPService._();
return _instance!;
}
/// 싱글톤 인스턴스 (GetIt 서비스 로케이터에 위임)
static IIAPService get instance => GetIt.instance<IIAPService>();
// ===========================================================================
// 상수
@@ -109,6 +110,7 @@ class IAPService {
// ===========================================================================
/// IAP 서비스 초기화
@override
Future<void> initialize() async {
if (_isInitialized) return;
@@ -201,9 +203,11 @@ class IAPService {
// ===========================================================================
/// 디버그 모드 IAP 시뮬레이션 활성화 여부
@override
bool get debugIAPSimulated => _debugIAPSimulated;
/// 디버그 모드 IAP 시뮬레이션 토글
@override
set debugIAPSimulated(bool value) {
_debugIAPSimulated = value;
if (kDebugMode) {
@@ -217,18 +221,21 @@ class IAPService {
// ===========================================================================
/// 광고 제거 구매 여부
@override
bool get isAdRemovalPurchased {
if (kDebugMode && _debugIAPSimulated) return true;
return _adRemovalPurchased;
}
/// 스토어 가용성
@override
bool get isStoreAvailable => _isAvailable;
/// 광고 제거 상품 정보
ProductDetails? get removeAdsProduct => _removeAdsProduct;
/// 광고 제거 상품 가격 문자열
@override
String get removeAdsPrice {
if (_removeAdsProduct != null) {
return _removeAdsProduct!.price;
@@ -246,6 +253,7 @@ class IAPService {
// ===========================================================================
/// 광고 제거 구매
@override
Future<IAPResult> purchaseRemoveAds() async {
// 디버그 모드 시뮬레이션
if (kDebugMode && _debugIAPSimulated) {
@@ -290,6 +298,7 @@ class IAPService {
// ===========================================================================
/// 구매 복원
@override
Future<IAPResult> restorePurchases() async {
// 디버그 모드 시뮬레이션
if (kDebugMode && _debugIAPSimulated) {
@@ -489,6 +498,7 @@ class IAPService {
// ===========================================================================
/// 리소스 해제
@override
void dispose() {
_subscription?.cancel();
_subscription = null;