Skip to content

Latest commit

Β 

History

History
470 lines (354 loc) Β· 13.9 KB

File metadata and controls

470 lines (354 loc) Β· 13.9 KB

WeaveDI

SPM Swift License Platform

A simple and powerful dependency injection framework for modern Swift Concurrency

πŸ“– Documentation: ν•œκ΅­μ–΄ | English | Official Docs | Roadmap

🎯 Key Features

  • ⚑ Swift Concurrency Native: Perfect support for async/await and Actor
  • πŸ”’ Type Safety: Compile-time type verification
  • πŸ“ TCA-Style Dependency Injection: @Injected/@Dependency with KeyPath and type-based access (v3.2.0)
  • πŸ—οΈ Optional AppDI: Use WeaveDIAppDI for module/factory registration only when needed
  • πŸ€– Auto Optimization: Automated dependency graph, Actor hop detection, type safety verification
  • πŸš€ Runtime Hot-Path Optimization: 50-80% performance improvement with TypeID + lock-free reads
  • πŸ§ͺ Test Friendly: Support for dependency mocking and isolation

πŸš€ Quick Start

Installation

dependencies: [
    .package(url: "https://github.com/Roy-wonji/WeaveDI.git", from: "3.4.0")
]

Basic Usage (v3.2.0)

import WeaveDI

// 1. App initialization - single entry point
await UnifiedDI.bootstrap { di in
    di.register(UserServiceProtocol.self) { UserService() }
    di.register(Networking.self) { NetworkClient() }
}

// 2. TCA-style @Injected/@Dependency usage (recommended)
class ViewModel {
    @Injected(\.userService) var userService
    @Dependency(\.networkClient) var networkClient

    func loadData() async {
        let data = await userService.fetchData()
    }
}

// 3. Define dependencies with InjectedKey
extension InjectedValues {
    var userService: UserServiceProtocol {
        get { self[UserServiceKey.self] }
        set { self[UserServiceKey.self] = newValue }
    }
}

struct UserServiceKey: InjectedKey {
    static var liveValue: UserServiceProtocol = UserService()
    static var testValue: UserServiceProtocol = UserService()
    static var previewValue: UserServiceProtocol = UserService()
}

App Module Registration (Optional: WeaveDIAppDI)

import WeaveDI
import WeaveDIAppDI

await UnifiedDI.bootstrap { _ in
    await UnifiedDI.registerDi { register in
        [
            register.authRepositoryImplModule(),
            register.authUseCaseImplModule()
        ]
    }
}

DiModuleFactory - Common DI Dependency Management (v3.3.4+)

WeaveDI v3.3.4 introduces DiModuleFactory for systematic management of common DI dependencies like Logger, Config, etc.

import WeaveDI
import WeaveDIAppDI

// DiModuleFactory usage
var diFactory = DiModuleFactory()

// Add common DI dependencies (actual API)
diFactory.addDependency(Logger.self) {
    ConsoleLogger()
}

diFactory.addDependency(APIConfig.self) {
    APIConfig(baseURL: "https://api.example.com")
}

// Use with ModuleFactoryManager
var factoryManager = ModuleFactoryManager()
factoryManager.diFactory = diFactory

// Other factories can also be configured together
factoryManager.repositoryFactory.addRepository(UserRepository.self) {
    UserRepositoryImpl()
}

factoryManager.useCaseFactory.addUseCase(
    AuthUseCase.self,
    repositoryType: UserRepository.self,
    repositoryFallback: { UserRepositoryImpl() }
) { repo in
    AuthUseCaseImpl(repository: repo)
}

// Register all modules to DI container
await factoryManager.registerAll(to: WeaveDI.Container.live)

Key Features:

  • πŸ“¦ Common Dependency Management: Systematically manage dependencies used throughout the app like Logger, Config
  • πŸ”„ Automatic Registration: Integrates with ModuleFactoryManager for automatic DI container registration
  • 🎯 Type Safety: Compile-time type verification for safer DI

πŸ†• Latest Updates (v3.4.0)

WeaveDI.builder Pattern Support πŸ—οΈ

New fluent API for more intuitive dependency registration:

// New builder pattern - automatic type inference!
WeaveDI.builder
    .register { UserServiceImpl() }    // Automatically registered as UserService
    .register { ConsoleLogger() }      // Automatically registered as Logger
    .register { NetworkClientImpl() }  // Automatically registered as NetworkClient
    .configure()

// Individual registration also supported
WeaveDI.register { UserServiceImpl() }  // Simple one-liner

// Environment-based registration
WeaveDI.registerForEnvironment { env in
    if env.isDebug {
        env.register { MockUserService() as UserService }
        env.register { DebugLogger() as Logger }
    } else {
        env.register { UserServiceImpl() as UserService }
        env.register { ProductionLogger() as Logger }
    }
}

SwiftUI-Style @DependencyConfiguration ⚑

Declare dependencies declaratively like SwiftUI's ViewBuilder:

// SwiftUI-style declarative registration
@DependencyConfiguration
var appDependencies {
    UserServiceImpl()           // Automatically registered as UserService
    RepositoryImpl()            // Automatically registered as Repository

    // Conditional registration supported
    if ProcessInfo.processInfo.environment["DEBUG"] != nil {
        DebugLogger() as Logger
    } else {
        ProductionLogger() as Logger
    }
}

// Call once at app startup
appDependencies.configure()

// Environment-specific configuration also supported
let productionDeps = DependencyEnvironment.production {
    UserServiceImpl()
    ProductionLogger() as Logger
    RealNetworkClient() as NetworkClient
}

let developmentDeps = DependencyEnvironment.development {
    UserServiceImpl()
    ConsoleLogger() as Logger
    MockNetworkClient() as NetworkClient
}

#if DEBUG
developmentDeps.configure()
#else
productionDeps.configure()
#endif

Module Structure Improvements πŸ“¦

WeaveDI is now more systematically organized with clear role separation:

  • WeaveDICore: Core DI engine (@Injected, UnifiedDI, DIContainer)
  • WeaveDIAppDI: App-level DI management (ModuleFactoryManager, DiModuleFactory)
  • WeaveDITCA: TCA-dedicated integration (conflict resolution complete)
  • WeaveDIMacros: Swift macro support (@Component, @AutoRegister)
  • WeaveDIOptimizations: Performance optimization (AutoDI, graph optimization)
  • WeaveDIMonitoring: Real-time monitoring (performance tracking, health checks)
  • WeaveDINeedleCompat: Uber Needle compatibility
  • WeaveDICompat: Legacy compatibility support
  • WeaveDITools: CLI tools and utilities

TCA Conflict Resolution πŸ”§

Type conflicts with The Composable Architecture are completely resolved:

// TCA and WeaveDI can now be used together safely
struct AppFeature: Reducer {
    @Dependency(\.userService) var userService: UserService  // TCA

    struct State {
        @Injected var logger: Logger  // WeaveDI - no conflicts!
    }
}

🎨 Swift Macro Support (v3.2.1+)

WeaveDI provides powerful Swift macros for compile-time optimization and Needle-style architecture.

@Component - Needle-style Components (10x faster)

import WeaveDI

@Component
public struct UserComponent {
    @Provide var userService: UserService = UserService()
    @Provide var userRepository: UserRepository = UserRepository()
    @Provide var authService: AuthService = AuthService()
}

// Automatically generates at compile-time:
// UnifiedDI.register(UserService.self) { UserService() }
// UnifiedDI.register(UserRepository.self) { UserRepository() }
// UnifiedDI.register(AuthService.self) { AuthService() }

@AutoRegister - Automatic Dependency Registration

@AutoRegister(lifetime: .singleton)
class DatabaseService: DatabaseServiceProtocol {
    // Automatically registered with UnifiedDI
}

@AutoRegister(lifetime: .transient)
class RequestHandler: RequestHandlerProtocol {
    // Creates new instance every time
}

@DIActor - Swift Concurrency Optimization

@DIActor
public final class AutoMonitor {
    public static let shared = AutoMonitor()

    // All methods become automatically thread-safe
    public func onModuleRegistered<T>(_ type: T.Type) {
        // Actor-isolated safe operations
    }
}

@DependencyGraph - Compile-time Validation

@DependencyGraph([
    UserService.self: [UserRepository.self, Logger.self],
    UserRepository.self: [DatabaseService.self],
    DatabaseService.self: [],
    Logger.self: []
])
class ApplicationDependencyGraph {
    // βœ… Validates circular dependencies at compile-time
}

Performance Comparison (WeaveDI vs Other Frameworks)

Framework Registration Resolution Memory Concurrency
Swinject ~1.2ms ~0.8ms High Manual locks
Needle ~0.8ms ~0.6ms Medium Limited
WeaveDI ~0.2ms ~0.1ms Low Native async/await

For more detailed macro usage, see WeaveDI Macros Guide.

πŸš€ Runtime Hot-Path Optimization (v3.2.0)

Micro-optimization features for high-performance applications.

Enable Optimization

import WeaveDI

// Enable optimization mode (existing APIs work unchanged)
UnifiedRegistry.shared.enableOptimization()

// Existing code gets performance improvements without changes
let service = await UnifiedDI.resolve(UserService.self)

Core Optimization Techniques

  1. TypeID + Index Access: Dictionary β†’ Array slot for O(1) access
  2. Lock-Free Reads: Snapshot approach eliminates read contention
  3. Inline Optimization: Reduced function call overhead
  4. Factory Chain Elimination: Direct call paths remove intermediate steps
  5. Scope-Specific Storage: Optimized separation of singleton/session/request scopes

Expected Performance Improvements

Scenario Improvement Description
Single-threaded resolve 50-80% faster TypeID + direct access
Multi-threaded reads 2-3x throughput Lock-free snapshots
Complex dependencies 20-40% faster Chain flattening

Run Benchmarks

swift run -c release Benchmarks --count 100k --quick

For detailed information, see PERFORMANCE-OPTIMIZATION.md.

πŸ“š Core APIs

Registration API

// Core recommended: register inside bootstrap
UnifiedDI.bootstrap { di in
    di.register(ServiceProtocol.self) { ServiceImpl() }
    di.register(UserRepositoryProtocol.self) { UserRepositoryImpl() }
}

Property Wrappers

Property Wrapper Purpose Example Status
@Injected TCA-style injection (recommended) @Injected(\.service) var service βœ… v3.2.0
@Dependency TCA-style injection (same storage) @Dependency(\.service) var service βœ… v3.2.0
@Factory Factory pattern (new instance) @Factory var generator: Generator βœ… Maintained
@Inject Basic injection (legacy) @Inject var service: Service? ⚠️ Deprecated (v3.2.0+)
@SafeInject Safe injection (legacy) @SafeInject var api: API? ⚠️ Deprecated (v3.2.0+)

πŸ“– Migration Guide: @Injected Documentation | AppDI Simplification

Resolution API

// General resolution
let service = await UnifiedDI.resolve(UserService.self)

// Safe resolution (with error handling)
let service: UserService = try await UnifiedDI.resolveSafely(UserService.self)

// KeyPath resolution
let repository = await UnifiedDI.resolve(\.userRepository)

// Scoped resolution
let sessionService = await UnifiedDI.resolveScoped(SessionService.self, scope: .session)

⚑ Auto Performance Optimization

// Automatically optimized after multiple uses
for _ in 1...15 {
    let service = UnifiedDI.resolve(UserService.self)
}

// Optimized types are automatically logged
// ⚑ Auto optimized: UserService (15 uses)

πŸ§ͺ Testing

// Test initialization
@MainActor
override func setUp() {
    UnifiedDI.releaseAll()

    // Register test dependencies
    _ = UnifiedDI.register(UserService.self) {
        MockUserService()
    }
}

πŸ“‹ Auto-Collected Information

// πŸ”„ Auto-generated dependency graph
UnifiedDI.autoGraph

// ⚑ Auto-optimized types
UnifiedDI.optimizedTypes

// ⚠️ Circular dependencies
UnifiedDI.circularDependencies

// πŸ“Š Usage statistics
UnifiedDI.stats

Logging Control

UnifiedDI.setLogLevel(.registration)  // Registration only
UnifiedDI.setLogLevel(.optimization)  // Optimization only
UnifiedDI.setLogLevel(.errors)       // Errors/warnings only
UnifiedDI.setLogLevel(.off)          // Turn off logging

πŸ”„ Migration from v2.x

// v2.x
let service = WeaveDI.Container.live.resolve(UserService.self)

// v3.x (recommended)
let service = await UnifiedDI.resolve(UserService.self)

// or still supported
let service = UnifiedDI.resolve(UserService.self)

πŸ“– Documentation

🀝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

πŸ“„ License

WeaveDI is released under the MIT license. See LICENSE for details.


Built with ❀️ for the Swift community