2023 08 14 08시 Amit Shekhar는 말했다. "Android Developer, please understand Dependency Injection really well before you jump into Dagger/Dagger-Hilt/Koin" DI라는 용어는 이전에도 많이 언급되었지만 제대로 공부하는게 좋을 거 같다.
의존성 주입은 객체 지향의 프로그래밍에서 중요한 디자인 패턴 중 하나로, 객체가 자신이 사용하는 의존성(다른 객체나 서비스)을 직접 생성하거나 조회하지 않고 외부에서 주입받는 기법
1990년대 후반: 마틴 파울러와 그의 동로들에 의해 정립되기 시작, 의존성 주입의 원리는 객체간의 느슨한 결합을 통해 코드의 재사용성, 유지보수, 테스트 용이성을 증가시키려는 목표
2004년: 마틴파울러가 "Inversion of Control Continers and the Dependency Injection pattern"이라는 글을 통해 의존성 주입이라는 용어를 처음 도입하고 이에 대해 설명
2000년대: 이 시기에 Java 등의 프로그래밍 언어와 환경에서 Spring Framework와 같은 프레임워크가 등장하면서 DI패턴이 대중화
이후의 발전: 2010년대에 들어서 DI는 다양한 프로그램이 언어와 플랫폼에서 점점 더 널리 채택되었습니다. Google Guice, Microsoft의 Unity, Dagger등과 같은 많은 라이브러리와 프레임워크가 등장하여 이 패턴을 적용하는 것을 더욱 쉽게 만들었습니다.
웹 애플리케이션에서 DI는 컨트롤러, 서비스, 저장소 클래스 등 간의 의존성을 관리하는데 사용. Spring Framewokr와 ASP.NET Core와 같은 웹프레임워크에서 일반적으로 사용
단위 테스트 및 통합 테스트에서 DI는 테스트하기 어려운 외부 의존성을 모의객체(mock objects)나 가짜 객체(fake objects)로 쉽게 교체할 수 있게 해줍니다. 이를 통해 테스트의 격리와 반복 가능성을 향상
Android와 같은 모바일 개발환경에서도 Dagger와 같은 DI 라이브러리가 사용되어 의존성 관리를 도와줍니다.
게임에서 DI는 게임의 다양한 컴포넌트와 시스템 간의 의존성을 관리하는데 사용.
마이크로서비스 아키텍처에서 DI는 각 서비스 간의 상호작용을 단순화하고, 서비스 간의 결합도를 줄임
플러그인 아키텍처에서 DI는 확장 가능한 방식으로 서드파티 플러그인과 메인 애플리케이션 간의 의존성을 관리
IoT 애플리케이션 및 임베디드 시스템에서도 DI를 사용하여 하드웨어와 소프트웨어 컴포넌트 간의 상호 작용을 간소화하고 테스트를 용이하게 할 수 있다.
@Module
class NetworkModule {
@Provides
fun provideHttpClient(): OkHttpClient {
return OkHttpClient.Builder().build()
}
}
컴포넌트 생성하기
@Component(modules = [NetworkModule::class])
interface AppComponent {
fun inject(activity: MainActivity)
}
의존성 주입하기
class MainActivity : AppCompatActivity() {
@Inject
lateinit var httpClient: OkHttpClient
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
DaggerAppComponent.create().inject(this)
// httpClient 사용하기
}
}
kotlin
Copy code
val appModule = module {
single { OkHttpClient.Builder().build() }
}
Koin 시작하기
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
startKoin {
modules(appModule)
}
}
}
의존성 주입하기
kotlin
Copy code
class MainActivity : AppCompatActivity() {
private val httpClient: OkHttpClient by inject()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// httpClient 사용하기
}
}
@Module
@InstallIn(SingletonComponent::class)
object NetworkModule {
@Provides
fun provideHttpClient(): OkHttpClient {
return OkHttpClient.Builder().build()
}
}
의존성 주입 준비하기
@HiltAndroidApp
class MyApplication : Application()
kotlin
Copy code
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
@Inject
lateinit var httpClient: OkHttpClient
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// httpClient 사용하기
}
}
1) 의존성 주입을 알아보기전이 의존성이란 무엇인가?
객체 지향프로그래밍에서 클래스간에 의존성이 있다는 것은 클래스간에 의존관계가 있다는 것을 뜻한다. 즉, 의존관계란 한 클래스가 바뀔 때 다른 클래스가 영향을 받는다는 것
2) 의존성 주입이란?