Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Kotlin 在Android之外使用Dagger2_Kotlin_Architecture_Dagger 2_Clean Architecture - Fatal编程技术网

Kotlin 在Android之外使用Dagger2

Kotlin 在Android之外使用Dagger2,kotlin,architecture,dagger-2,clean-architecture,Kotlin,Architecture,Dagger 2,Clean Architecture,我最近开始学习匕首。为了做到这一点,我决定编写一个简单的控制台应用程序,以了解各种dagger功能(如模块、组件、子组件和组件依赖项)在应用程序体系结构中是如何结合在一起的。由于我并没有真正理解它,并且考虑到要找到一个使用dagger2创建的应用程序示例是多么困难,它不是Android应用程序,所以我决定在这里提出一个问题 第一个也是可能是最重要的问题是:dagger2甚至可以在android之外使用吗 如果是,那么让我们考虑一个简单的应用架构:我们有数据层、服务层和UI层 数据层可能由某种外观

我最近开始学习匕首。为了做到这一点,我决定编写一个简单的控制台应用程序,以了解各种dagger功能(如模块、组件、子组件和组件依赖项)在应用程序体系结构中是如何结合在一起的。由于我并没有真正理解它,并且考虑到要找到一个使用dagger2创建的应用程序示例是多么困难,它不是Android应用程序,所以我决定在这里提出一个问题

第一个也是可能是最重要的问题是:dagger2甚至可以在android之外使用吗

如果是,那么让我们考虑一个简单的应用架构:我们有数据层、服务层和UI层

数据层可能由某种外观组成: (以下代码段将用Kotlin编写)

服务层将更简单:

@Singleton
class Service @Inject constructor(repository: Repository) {
    fun doSomeStuffToEntity(entity: Entity) {}
}

@Singleton
class AnotherService @Inject constructor(repository: Repository) {
    fun doSomeStuffToEntity(entity: Entity) {}
}
但是当涉及到UI层时,它变得有点不明显。假设我有一些类似android的活动:

interface Activity : Runnable
还有一些管理这些活动的课程:

class UserInterfaceManager {

    val activityStack: Stack<Activity> = Stack()
    val eventQueue: Queue<Runnable> = LinkedList()

    fun startActivity(activity: Activity) = postRunnable {
        activityStack.push(activity)
        activity.run()
    }

    fun postRunnable(callback: () -> Unit) = eventQueue.add(callback)

    fun stopActivity() { TODO() }
    
    //other

}
但是,注射到哪里去了?把它放在UserInterfaceManager中是没有意义的,因为活动很可能需要它的一个实例,这将创建一个循环依赖关系。 我也不喜欢从某种静态方法/属性获取组件并在启动时从内部注入活动的想法,因为它会在每个活动中创建重复的代码行

此外,组件和子组件在这种体系结构中的位置如何?为什么不创建单独的 组件,只公开存储库,并将其声明为应用程序组件的依赖项,这将进一步隔离细节和抽象?也许我应该声明这个组件是一个服务组件的依赖项,它将强制执行层架构,因为组件只能使用组件接口中公开的类型?或者我应该只在需要自定义作用域并在其他地方使用模块时才使用Component


我只是总体上认为我错过了匕首的大局。我将非常感谢您的回答、解释以及文章和其他资源的链接,这将使我更好地理解它。

从Android开发者的角度来看,我完全理解您的观点。我也问了自己这个问题。在普通Java/Kotlin世界中构造对象的方式有点不同。主要原因是基本Android组件(
活动
/
片段
)不允许构造函数注入

不过,你的问题的答案很简单。Dagger
组件
负责对象创建,作为开发人员,您可以控制特定于对象的组件提供的内容。让我们在您的场景中使用它,并提供一些您可能感兴趣的对象:

@Singleton
@Component(modules = [InMemoryPersistenceModule::class])
interface ApplicationComponent {
    val service: Service
    val anotherService: AnotherService
}
ApplicationComponent
应理解为整个应用程序的组件。它与Android的
应用程序
类没有任何关系。现在,您只需创建组件并让Dagger实例化您的对象:

val component = DaggerApplicationComponent.create()
val anotherService: AnotherService = component.anotherService
val service: AnotherService = component.service

从Android开发者的角度来看,我完全理解你的观点。我也问了自己这个问题。在普通Java/Kotlin世界中构造对象的方式有点不同。主要原因是基本Android组件(
活动
/
片段
)不允许构造函数注入

不过,你的问题的答案很简单。Dagger
组件
负责对象创建,作为开发人员,您可以控制特定于对象的组件提供的内容。让我们在您的场景中使用它,并提供一些您可能感兴趣的对象:

@Singleton
@Component(modules = [InMemoryPersistenceModule::class])
interface ApplicationComponent {
    val service: Service
    val anotherService: AnotherService
}
ApplicationComponent
应理解为整个应用程序的组件。它与Android的
应用程序
类没有任何关系。现在,您只需创建组件并让Dagger实例化您的对象:

val component = DaggerApplicationComponent.create()
val anotherService: AnotherService = component.anotherService
val service: AnotherService = component.service

我还写了一篇关于这个问题的文章。这可能对你也有帮助。我还写了一篇关于这个问题的文章。这也可能对你有帮助。
@Singleton
@Component(modules = [InMemoryPersistenceModule::class])
interface ApplicationComponent {
    val service: Service
    val anotherService: AnotherService
}
val component = DaggerApplicationComponent.create()
val anotherService: AnotherService = component.anotherService
val service: AnotherService = component.service