WeaveDI 3.2.0 introduces automatic dependency registration, eliminating the need for manual registerRepositories() and registerUseCases() calls. The framework now automatically invokes these methods through the improved registerAllDependencies() system.
// ❌ Old approach - manual calls required
@main
struct MyApp: App {
init() {
Task {
await WeaveDI.Container.bootstrap { container in
// Manual registration
await WeaveDI.Container.registerRepositories()
await WeaveDI.Container.registerUseCases()
}
}
}
}// ✅ New approach - automatic registration
@main
struct MyApp: App {
init() {
WeaveDI.Container.bootstrapInTask { @DIContainerActor _ in
await AppDIManager.shared.registerDefaultDependencies()
}
}
}The AppDIManager.shared.registerDefaultDependencies() method automatically calls both registerRepositories() and registerUseCases():
// AppDIManager automatically registers all dependencies
public actor AppDIManager {
public static let shared = AppDIManager()
public func registerDefaultDependencies() async {
// Automatically calls these methods
await WeaveDI.Container.registerRepositories()
await WeaveDI.Container.registerUseCases()
#if DEBUG
print("✅ AppDIManager.registerDefaultDependencies() completed")
#endif
}
}extension WeaveDI.Container {
private static let helper = RegisterModule()
/// 📦 Repository Registration
static func registerRepositories() async {
let repositories = [
helper.exchangeRepositoryModule(),
helper.userRepositoryModule(),
// Add more repository modules...
]
await repositories.asyncForEach { module in
await module.register()
}
}
/// 🔧 UseCase Registration
static func registerUseCases() async {
let useCases = [
helper.exchangeUseCaseModule(),
helper.userUseCaseModule(),
// Add more useCase modules...
]
await useCases.asyncForEach { module in
await module.register()
}
}
}extension RegisterModule {
var exchangeUseCaseModule: @Sendable () -> Module {
makeUseCaseWithRepository(
ExchangeRateInterface.self,
repositoryProtocol: ExchangeRateInterface.self,
repositoryFallback: MockExchangeRepositoryImpl(),
factory: { repo in
ExchangeUseCaseImpl(repository: repo)
}
)
}
var exchangeRepositoryModule: @Sendable () -> Module {
makeDependency(ExchangeRateInterface.self) {
ExchangeRepositoryImpl()
}
}
}- Before: Manual registration calls in every app
- After: Framework handles registration automatically
// Clean and simple app initialization
@main
struct CurrencyConverterApp: App {
init() {
WeaveDI.Container.bootstrapInTask { @DIContainerActor _ in
await AppDIManager.shared.registerDefaultDependencies()
}
}
var body: some Scene {
WindowGroup {
ContentView()
}
}
}Organize dependencies by feature using module extensions:
// Authentication Module
extension RegisterModule {
var authRepositoryModule: @Sendable () -> Module { ... }
var authUseCaseModule: @Sendable () -> Module { ... }
}
// User Module
extension RegisterModule {
var userRepositoryModule: @Sendable () -> Module { ... }
var userUseCaseModule: @Sendable () -> Module { ... }
}
// Currency Module
extension RegisterModule {
var exchangeRepositoryModule: @Sendable () -> Module { ... }
var exchangeUseCaseModule: @Sendable () -> Module { ... }
}Remove explicit registerRepositories() and registerUseCases() calls from your app initialization:
// ❌ Remove these lines
await WeaveDI.Container.registerRepositories()
await WeaveDI.Container.registerUseCases()Ensure your WeaveDI.Container extensions override the default implementations:
extension WeaveDI.Container {
static func registerRepositories() async {
// Your repository registration logic
}
static func registerUseCases() async {
// Your useCase registration logic
}
}Use bootstrapInTask with AppDIManager to register dependencies:
@main
struct MyApp: App {
init() {
WeaveDI.Container.bootstrapInTask { @DIContainerActor _ in
await AppDIManager.shared.registerDefaultDependencies()
}
}
}Use asyncForEach for parallel module registration:
static func registerRepositories() async {
let repositories = [
helper.exchangeRepositoryModule(),
helper.userRepositoryModule(),
helper.authRepositoryModule(),
]
// Registers all modules in parallel
await repositories.asyncForEach { module in
await module.register()
}
}// AutoDIRegistry.swift
import WeaveDI
extension WeaveDI.Container {
private static let helper = RegisterModule()
static func registerRepositories() async {
let repositories = [
helper.exchangeRepositoryModule(),
]
await repositories.asyncForEach { module in
await module.register()
}
}
static func registerUseCases() async {
let useCases = [
helper.exchangeUseCaseModule(),
]
await useCases.asyncForEach { module in
await module.register()
}
}
}
extension RegisterModule {
var exchangeUseCaseModule: @Sendable () -> Module {
makeUseCaseWithRepository(
ExchangeRateInterface.self,
repositoryProtocol: ExchangeRateInterface.self,
repositoryFallback: MockExchangeRepositoryImpl(),
factory: { repo in
ExchangeUseCaseImpl(repository: repo)
}
)
}
var exchangeRepositoryModule: @Sendable () -> Module {
makeDependency(ExchangeRateInterface.self) {
ExchangeRepositoryImpl()
}
}
}
// App.swift
@main
struct CurrencyConverterApp: App {
init() {
WeaveDI.Container.bootstrapInTask { @DIContainerActor _ in
await AppDIManager.shared.registerDefaultDependencies()
}
}
var body: some Scene {
WindowGroup {
ContentView()
}
}
}Group related dependencies into feature-based modules:
// Feature: Authentication
extension RegisterModule {
var authModule: @Sendable () -> [Module] {
[
authRepositoryModule(),
authUseCaseModule(),
]
}
}// ✅ Good - clear and descriptive
var exchangeRateRepositoryModule: @Sendable () -> Module { ... }
var userAuthenticationUseCaseModule: @Sendable () -> Module { ... }
// ❌ Avoid - unclear names
var repo1Module: @Sendable () -> Module { ... }
var module2: @Sendable () -> Module { ... }extension RegisterModule {
/// Exchange rate repository module
/// Provides currency exchange rate data access
var exchangeRepositoryModule: @Sendable () -> Module {
makeDependency(ExchangeRateInterface.self) {
ExchangeRepositoryImpl()
}
}
}If dependencies aren't being registered automatically:
- Verify you have
registerRepositories()andregisterUseCases()extensions - Check that
bootstrapis being called - Ensure your extensions are in the same target as your app
Enable debug logging to see registration progress:
#if DEBUG
extension WeaveDI.Container {
static func registerRepositories() async {
print("📦 Registering repositories...")
// ... registration logic
print("✅ Repositories registered")
}
}
#endif- @Injected - Modern dependency injection
- Module System - Module-based organization
- Testing Guide - Testing with automatic registration