N26 모루로 가는 경로
N26 안드로이드 애플리케이션current codebase는 하나의 모노 저장소에 100만 줄 코드, 280여 개의 모듈과 30여 명의 엔지니어가 있는데 이들은 4개의 국가와 시간대에서 일한다.우리의 모듈은 기능과 라이브러리로 나뉘는데, 여러 해 동안 'Sample Apps' 를 사용해 왔다. 왜냐하면 우리의 전체 응용 프로그램 구축 시간은 20분이 걸릴 수 있기 때문이다.
오늘 저는 Dagger와 제가 회사 내부에 있는 이야기, 우리가 왜 Anvil을 채용했는지, 우리가 직면한 도전, 그리고 지금까지의 결과가 어떠한지 공유할 것입니다.
비수, (오 마이 갓)
N26은 유구한 비수 역사를 가지고 있다.우리는 그것을 사용한 지 이미 여러 해가 되었다. 우리는 그것을 바탕으로 우리의 맞춤형 라이브러리와 라이브러리를 개발했고, 우리의 많은 구조 결정은 Dagger 특성에 의해 이루어진 것이다.
비수는 우수하지만 코틀린과 함께 사용하면 가격이 비싸다.우리가 성장할수록, 고발당할 수도 있다.스텁 생성 문제, 느린 구축 시간, 끊임없이 증가하는 템플릿 라인@dagger.Component
, 복잡성 때문에 신입 가입자는 도형에 접촉하지 않습니다..
해결 방안을 찾기 위해 우리는 찾았다Hilt by Google.우리는 그들이 제기한 많은 생각, 예를 들면 Monolithic Component과testing philosophy를 좋아한다.그러나 이런 균형은 우리에게 그다지 좋지 않다. 이전은 고통스러울 것이고, 수개월에서 수년의 시간이 걸릴 것이며, 바이트 조작과 추가 KAPT 프로세서를 좋아하지 않을 뿐만 아니라.
동시에 또 다른 해결 방안이 등장했다. 그것은 서로 다른 방식으로 같은 문제를 해결했다. Anvil.
Anvil is a Kotlin compiler plugin to make dependency injection with Dagger easier by automatically merging Dagger modules and component interfaces.
칼을 갈다
모루가 우리에게 미치는 영향을 이해하기 위해서 우리는 일련의 실험부터 시작한다.첫 번째는 몇 개의 모듈을 연결하는 동시에 뒤로 호환성을 유지하며 어떠한 기능 개발자에게도 영향을 주지 않는다.몇 시간 안에 우리는 마침내 완성했다.일주일 동안, 우리는 많은 모듈이 모루를 사용한다.우리는 어떤 뚜렷한 구축 시 영향도 발견하지 못했다.
우리는 결과에 대해 매우 만족한다.우리는 더욱 웅장하게 하기로 결정했다. 우리는 코드 라이브러리에서 돋보이는 모노리치 모듈을 선택하여 Anvil로 완전히 옮긴 다음에 이 모노리치를 몇 개의 작은 라이브러리로 나누었다.우리는 몇 개월의 시간을 들여 이 목표를 달성했지만, 우리는 성공했고, 뚜렷한 구축 시 영향을 발견하지 못했다.
우리가 올바른 길을 걷고 있는지 확인하기 위해서, 우리는 Anvil의 앞뒤 몇 개의 가장 복잡한 모듈 간의 관계를 그렸다.회사의 프라이버시를 고려하여 모든 텍스트가 모호하지만 주의 화살표를 통해 긍정적인 영향을 볼 수 있습니다.
마지막으로, 우리는 전체 Anvil을 사용하기로 결정했다. 우리는 모든 가능한 모듈에서 Anvil's Dagger Factory generation (당시 20개가 넘었다).우리는 단일 모듈의 구축 시간이 약 50% 증가했고 예시 프로그램의 구축 시간이 약 10% 높아졌으며 Anvil이 KAPT에 의존하지 않기 때문에 이 모듈에서 어떠한 KAPT 문제도 보지 못했다.
많은 개선이 있었지만, 우리는 우리가 더 나아갈 수 있을 것이라고 믿는다. 우리는 칼자루에서 좋은 물건을 가져가서 모루로 가져갈 수 있을 것이라고 믿는다.
모루자루
우리는 모루를 사용할 때 우리가 좋아하는 칼자루를 사용하기로 결정했다.
첫 번째는 하나의 단일한 전체 구성 요소를 제공하는 것입니다. 이를 위해 우리는 구성 요소를 통합하고 Anvil@ContributesTo
귀속 모듈을 사용합니다.시간이 오래 걸리고 도전적이지만 효과가 좋다.
두 번째는 일부 Jetpack 라이브러리를 지원합니다.우리는 FragmentFactory
부터 가능한 한 구조 함수 주입기를 이용한다.우리는 @FragmentKey
를 만들고 Dagger의 다중 연결을 사용하여 모든 것을 연결합니다.다음은 코드의 모양입니다.
@ContributesBinding(Singleton::class, FragmentFactory::class)
class MultibindingFragmentFactory @Inject constructor(
private val map: Map<Class<out Fragment>, @JvmSuppressWildcards Provider<Fragment>>
) : FragmentFactory() {
override fun instantiate(classLoader: ClassLoader, className: String): Fragment {
val fragmentClass = loadFragmentClass(classLoader, className)
return map[fragmentClass]?.get() ?: super.instantiate(classLoader, className)
}
}
@Target(
AnnotationTarget.CLASS,
AnnotationTarget.FUNCTION
)
@Retention(value = AnnotationRetention.RUNTIME)
@MapKey
annotation class FragmentKey(val value: KClass<out Fragment>)
class Activity : AppCompatActivity() {
private val component: MainComponent
get() = TODO("Retrieve your Monolith Component")
override fun onCreate(savedInstanceState: Bundle?) {
supportFragmentManager.fragmentFactory = component.getFragmentFactory()
super.onCreate(savedInstanceState)
}
}
이제 연결Fragment
하려면 다음을 간단히 수행할 수 있습니다.
@ContributesMultibinding(Singleton::class)
@FragmentKey(HomeFragment::class)
class HomeFragment @Inject constructor(
// Dependencies goes here. :)
) : Fragment()
세그먼트에 대한 자세한 내용은 official guide를 참조하십시오.
전체적인 구성 요소를 가지고 Fragment에 의존하는 구조 함수 주입기는 프로그램의 어느 위치에서든 세션을 호출할 수 있음을 의미하며, 일은 모두 성공할 것이다.이런 종류에 대해 말하자면, 범위의 경계는 매우 직관적으로 변했다.객체 주입Fragment
이 세션 범위이고 객체 주입ViewModel
이 뷰 모델 범위인 경우또한 SessionScope
및 Singleton
범위를 제공합니다.ViewModels
의 간단한 Provider<ViewModel>
또는 AssistedInject
에 대해 SavedStateHandle
의 실례가 필요하다면 됩니다.
마지막으로 테스트:Anvil은 replace module feature 버전을 제공하여 테스트 과정에서 새로운 의존 관계를 제공합니다.이를 위해, 우리는 testing
라는 조수 모듈을 만들었고, 생산 모듈을 대체하는 위조 의존항을 제공했다.테스트 클래스 경로에 testing
를 포함하는 개발자는 자동으로 우리의 테스트 실용 프로그램과 상호작용을 할 수 있다(또는 필요하면 자신의 것을 만들 수 있다).솔직히 지속적인 과정인 것 같다.
결론
Anvil은 강력하고 직접적인 해결 방안이다.그것은 하고 싶은 일을 할 뿐만 아니라 아주 잘한다.Dagger와의 긴밀한 협력 덕분에 고집을 부리지 않고 다른 라이브러리와 어떻게 통합할 것인지를 결정할 수 있습니다.
또한 KAPT에 의존하지 않는다는 사실은 대형 프로젝트에 있어 큰 장점이므로 모루를 사용할지 칼자루를 사용할지 결정할 때 이 점을 기억해야 한다.저는 전체적인 체험에 대해 기쁩니다. 저도 얼마나 많은 기능 개발자들이 KAPT에서 Anvil로 자발적으로 이전하기 시작했는지 보고 기쁩니다.
마지막으로 위에서 보듯이 칼자루의 많은 기능은 Anvil에서 실현할 수 있습니다.그러나 중요한 것은 모루가 은탄이 아니라는 것을 명심하는 것이다.팀에는 필요한 통합을 구축하기 위해 Dagger와 투입에 의존하는 사람이 있어야 합니다.
업데이트 2021.02.25
많은 사람들이 저에게 Hilt 기능(예를 들어 ViewModelScope,SavedStateHandle 등)을 어떻게 실현하는지 문의했을 때small showcase project를 만들었습니다.
업데이트 2021.03.19
업데이트MultibindingFragmentFactory
예제 및 showcase project를 사용하여 Anvil 2.2.0 의 신규 @ContributesMultibinding
를 사용할 수 있습니다.
크레디트
감사합니다,, 그리고 교정 평론!🔍
초기 피드백과 Anvil 창설에 특별히 감사드립니다!🔪
제 댓글이 마음에 드시면 트위터에 팔로우 해주세요.
표지 사진작가Lucy and the Anvil.
Reference
이 문제에 관하여(N26 모루로 가는 경로), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://dev.to/marcellogalhardo/n26-path-to-anvil-abd
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Anvil is a Kotlin compiler plugin to make dependency injection with Dagger easier by automatically merging Dagger modules and component interfaces.
모루가 우리에게 미치는 영향을 이해하기 위해서 우리는 일련의 실험부터 시작한다.첫 번째는 몇 개의 모듈을 연결하는 동시에 뒤로 호환성을 유지하며 어떠한 기능 개발자에게도 영향을 주지 않는다.몇 시간 안에 우리는 마침내 완성했다.일주일 동안, 우리는 많은 모듈이 모루를 사용한다.우리는 어떤 뚜렷한 구축 시 영향도 발견하지 못했다.
우리는 결과에 대해 매우 만족한다.우리는 더욱 웅장하게 하기로 결정했다. 우리는 코드 라이브러리에서 돋보이는 모노리치 모듈을 선택하여 Anvil로 완전히 옮긴 다음에 이 모노리치를 몇 개의 작은 라이브러리로 나누었다.우리는 몇 개월의 시간을 들여 이 목표를 달성했지만, 우리는 성공했고, 뚜렷한 구축 시 영향을 발견하지 못했다.
우리가 올바른 길을 걷고 있는지 확인하기 위해서, 우리는 Anvil의 앞뒤 몇 개의 가장 복잡한 모듈 간의 관계를 그렸다.회사의 프라이버시를 고려하여 모든 텍스트가 모호하지만 주의 화살표를 통해 긍정적인 영향을 볼 수 있습니다.
마지막으로, 우리는 전체 Anvil을 사용하기로 결정했다. 우리는 모든 가능한 모듈에서 Anvil's Dagger Factory generation (당시 20개가 넘었다).우리는 단일 모듈의 구축 시간이 약 50% 증가했고 예시 프로그램의 구축 시간이 약 10% 높아졌으며 Anvil이 KAPT에 의존하지 않기 때문에 이 모듈에서 어떠한 KAPT 문제도 보지 못했다.
많은 개선이 있었지만, 우리는 우리가 더 나아갈 수 있을 것이라고 믿는다. 우리는 칼자루에서 좋은 물건을 가져가서 모루로 가져갈 수 있을 것이라고 믿는다.
모루자루
우리는 모루를 사용할 때 우리가 좋아하는 칼자루를 사용하기로 결정했다.
첫 번째는 하나의 단일한 전체 구성 요소를 제공하는 것입니다. 이를 위해 우리는 구성 요소를 통합하고 Anvil@ContributesTo
귀속 모듈을 사용합니다.시간이 오래 걸리고 도전적이지만 효과가 좋다.
두 번째는 일부 Jetpack 라이브러리를 지원합니다.우리는 FragmentFactory
부터 가능한 한 구조 함수 주입기를 이용한다.우리는 @FragmentKey
를 만들고 Dagger의 다중 연결을 사용하여 모든 것을 연결합니다.다음은 코드의 모양입니다.
@ContributesBinding(Singleton::class, FragmentFactory::class)
class MultibindingFragmentFactory @Inject constructor(
private val map: Map<Class<out Fragment>, @JvmSuppressWildcards Provider<Fragment>>
) : FragmentFactory() {
override fun instantiate(classLoader: ClassLoader, className: String): Fragment {
val fragmentClass = loadFragmentClass(classLoader, className)
return map[fragmentClass]?.get() ?: super.instantiate(classLoader, className)
}
}
@Target(
AnnotationTarget.CLASS,
AnnotationTarget.FUNCTION
)
@Retention(value = AnnotationRetention.RUNTIME)
@MapKey
annotation class FragmentKey(val value: KClass<out Fragment>)
class Activity : AppCompatActivity() {
private val component: MainComponent
get() = TODO("Retrieve your Monolith Component")
override fun onCreate(savedInstanceState: Bundle?) {
supportFragmentManager.fragmentFactory = component.getFragmentFactory()
super.onCreate(savedInstanceState)
}
}
이제 연결Fragment
하려면 다음을 간단히 수행할 수 있습니다.
@ContributesMultibinding(Singleton::class)
@FragmentKey(HomeFragment::class)
class HomeFragment @Inject constructor(
// Dependencies goes here. :)
) : Fragment()
세그먼트에 대한 자세한 내용은 official guide를 참조하십시오.
전체적인 구성 요소를 가지고 Fragment에 의존하는 구조 함수 주입기는 프로그램의 어느 위치에서든 세션을 호출할 수 있음을 의미하며, 일은 모두 성공할 것이다.이런 종류에 대해 말하자면, 범위의 경계는 매우 직관적으로 변했다.객체 주입Fragment
이 세션 범위이고 객체 주입ViewModel
이 뷰 모델 범위인 경우또한 SessionScope
및 Singleton
범위를 제공합니다.ViewModels
의 간단한 Provider<ViewModel>
또는 AssistedInject
에 대해 SavedStateHandle
의 실례가 필요하다면 됩니다.
마지막으로 테스트:Anvil은 replace module feature 버전을 제공하여 테스트 과정에서 새로운 의존 관계를 제공합니다.이를 위해, 우리는 testing
라는 조수 모듈을 만들었고, 생산 모듈을 대체하는 위조 의존항을 제공했다.테스트 클래스 경로에 testing
를 포함하는 개발자는 자동으로 우리의 테스트 실용 프로그램과 상호작용을 할 수 있다(또는 필요하면 자신의 것을 만들 수 있다).솔직히 지속적인 과정인 것 같다.
결론
Anvil은 강력하고 직접적인 해결 방안이다.그것은 하고 싶은 일을 할 뿐만 아니라 아주 잘한다.Dagger와의 긴밀한 협력 덕분에 고집을 부리지 않고 다른 라이브러리와 어떻게 통합할 것인지를 결정할 수 있습니다.
또한 KAPT에 의존하지 않는다는 사실은 대형 프로젝트에 있어 큰 장점이므로 모루를 사용할지 칼자루를 사용할지 결정할 때 이 점을 기억해야 한다.저는 전체적인 체험에 대해 기쁩니다. 저도 얼마나 많은 기능 개발자들이 KAPT에서 Anvil로 자발적으로 이전하기 시작했는지 보고 기쁩니다.
마지막으로 위에서 보듯이 칼자루의 많은 기능은 Anvil에서 실현할 수 있습니다.그러나 중요한 것은 모루가 은탄이 아니라는 것을 명심하는 것이다.팀에는 필요한 통합을 구축하기 위해 Dagger와 투입에 의존하는 사람이 있어야 합니다.
업데이트 2021.02.25
많은 사람들이 저에게 Hilt 기능(예를 들어 ViewModelScope,SavedStateHandle 등)을 어떻게 실현하는지 문의했을 때small showcase project를 만들었습니다.
업데이트 2021.03.19
업데이트MultibindingFragmentFactory
예제 및 showcase project를 사용하여 Anvil 2.2.0 의 신규 @ContributesMultibinding
를 사용할 수 있습니다.
크레디트
감사합니다,, 그리고 교정 평론!🔍
초기 피드백과 Anvil 창설에 특별히 감사드립니다!🔪
제 댓글이 마음에 드시면 트위터에 팔로우 해주세요.
표지 사진작가Lucy and the Anvil.
Reference
이 문제에 관하여(N26 모루로 가는 경로), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://dev.to/marcellogalhardo/n26-path-to-anvil-abd
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
@ContributesBinding(Singleton::class, FragmentFactory::class)
class MultibindingFragmentFactory @Inject constructor(
private val map: Map<Class<out Fragment>, @JvmSuppressWildcards Provider<Fragment>>
) : FragmentFactory() {
override fun instantiate(classLoader: ClassLoader, className: String): Fragment {
val fragmentClass = loadFragmentClass(classLoader, className)
return map[fragmentClass]?.get() ?: super.instantiate(classLoader, className)
}
}
@Target(
AnnotationTarget.CLASS,
AnnotationTarget.FUNCTION
)
@Retention(value = AnnotationRetention.RUNTIME)
@MapKey
annotation class FragmentKey(val value: KClass<out Fragment>)
class Activity : AppCompatActivity() {
private val component: MainComponent
get() = TODO("Retrieve your Monolith Component")
override fun onCreate(savedInstanceState: Bundle?) {
supportFragmentManager.fragmentFactory = component.getFragmentFactory()
super.onCreate(savedInstanceState)
}
}
@ContributesMultibinding(Singleton::class)
@FragmentKey(HomeFragment::class)
class HomeFragment @Inject constructor(
// Dependencies goes here. :)
) : Fragment()
Anvil은 강력하고 직접적인 해결 방안이다.그것은 하고 싶은 일을 할 뿐만 아니라 아주 잘한다.Dagger와의 긴밀한 협력 덕분에 고집을 부리지 않고 다른 라이브러리와 어떻게 통합할 것인지를 결정할 수 있습니다.
또한 KAPT에 의존하지 않는다는 사실은 대형 프로젝트에 있어 큰 장점이므로 모루를 사용할지 칼자루를 사용할지 결정할 때 이 점을 기억해야 한다.저는 전체적인 체험에 대해 기쁩니다. 저도 얼마나 많은 기능 개발자들이 KAPT에서 Anvil로 자발적으로 이전하기 시작했는지 보고 기쁩니다.
마지막으로 위에서 보듯이 칼자루의 많은 기능은 Anvil에서 실현할 수 있습니다.그러나 중요한 것은 모루가 은탄이 아니라는 것을 명심하는 것이다.팀에는 필요한 통합을 구축하기 위해 Dagger와 투입에 의존하는 사람이 있어야 합니다.
업데이트 2021.02.25
많은 사람들이 저에게 Hilt 기능(예를 들어 ViewModelScope,SavedStateHandle 등)을 어떻게 실현하는지 문의했을 때small showcase project를 만들었습니다.
업데이트 2021.03.19
업데이트MultibindingFragmentFactory
예제 및 showcase project를 사용하여 Anvil 2.2.0 의 신규 @ContributesMultibinding
를 사용할 수 있습니다.
크레디트
감사합니다,, 그리고 교정 평론!🔍
초기 피드백과 Anvil 창설에 특별히 감사드립니다!🔪
제 댓글이 마음에 드시면 트위터에 팔로우 해주세요.
표지 사진작가Lucy and the Anvil.
Reference
이 문제에 관하여(N26 모루로 가는 경로), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://dev.to/marcellogalhardo/n26-path-to-anvil-abd
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
업데이트
MultibindingFragmentFactory
예제 및 showcase project를 사용하여 Anvil 2.2.0 의 신규 @ContributesMultibinding
를 사용할 수 있습니다.크레디트
감사합니다,, 그리고 교정 평론!🔍
초기 피드백과 Anvil 창설에 특별히 감사드립니다!🔪
제 댓글이 마음에 드시면 트위터에 팔로우 해주세요.
표지 사진작가Lucy and the Anvil.
Reference
이 문제에 관하여(N26 모루로 가는 경로), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://dev.to/marcellogalhardo/n26-path-to-anvil-abd
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Reference
이 문제에 관하여(N26 모루로 가는 경로), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/marcellogalhardo/n26-path-to-anvil-abd텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)