ControlNet

个人博客 << 分享一些有用的东西

LightIoC是一个通过依赖注入的Scala轻量化控制反转工具,发布在GitHub上,项目地址

添加依赖

Scala

这个库针对Scala 2.13.x, 2.12.x, 2.11.x进行编译,在Java8, 11, 16中通过测试。目前最新版本是0.3.0,请持续关注GitHub页面

SBT:

1
libraryDependencies += "space.controlnet" %% "lightioc" % "0.3.0"

Gradle:

1
implementation group: "space.controlnet", name: "lightioc_<scala_version>", version: "0.3.0"

Java

这个库提供了一个Java友好的API,可以在Java中使用LightIoC。详情可以看Java API

Gradle:

1
implementation group: "space.controlnet", name: "lightioc-api_2.13", version: "0.3.0"

快速开始

静态注册

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import space.controlnet.lightioc.Container

@Provider
class TopLevelClass

@Singleton
class TopLevelSingletonClass

@Provider(isObject = true)
object TopLevelObject

@Provider(stringId = "IdForThisClass")
class NamedProviderClass

@Provider(isObject = true)
object NestedClass {

@Provider
class InnerClass

@Provider(isObject = true)
object InnerObject
}

object Main extends App {
Container.init("<package name>")
}

动态注册

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import space.controlnet.lightioc.Container
import space.controlnet.lightioc.Util._

class Foo
class Bar {
var x: Int = _
var y: Int = _
}
object Baz
class Qux(foo: Foo)

object Main extends App {
// register Foo to self constructor in Transient scope
Container.register[Foo].toSelf.inTransientScope()
// register Bar to self constructor in Singleton scope
Container.register[Bar].toSelf.inSingletonScope()
// register Baz as well
Container.register[Baz.type].toSelf.inSingletonScope()
// register a constructor with parameters
Container.register[Qux].toConstructor(classOf[Foo]).inTransientScope()
// register a constant value
Container.register("A Number").toValue(123).inSingletonScope()
// register a factory
val barX = 1
val barY = 2
Container.register[Int]("Bar.x").toValue(barX).inSingletonScope()
Container.register[Int]("Bar.y").toValue(barY).inSingletonScope()
val factory: Factory[Bar] = Container => {
// do anything you want
val bar = new Bar
bar.x = Container.resolve[Int]("Bar.x")
bar.y = Container.resolve[Int]("Bar.y")
bar
}
Container.register[Bar].toFactory(factory).inTransientScope()
// register to another service (registry)
Container.register[Foo].toSelf.inTransientScope() // target service
Container.register("AnotherFoo").toService[Foo]
}

当然,也可以使用Scala特色的自定义运算符。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import space.controlnet.lightioc.Container
import space.controlnet.lightioc.BindingSetter.{ New, Self }

object Main extends App {
// register to value in Transient
Container.register("AString") -> "Hello IOC"
// register to constructor/class in Transient
Container.register[Foo] -> classOf[Foo]
// register to constructor/class in Singleton
Container.register[Bar] := classOf[Bar]
// register to self
Container.register[Baz.type] -> Self
// register to a constructor with parameters
Container.register[Qux] -> New(classOf[Foo])
// register to factory
Container.register[Bar] ~> factory
// register to service
Container.register("AnotherString") >> "AString"
}

动态获取

1
2
3
4
5
6
7
8
9
10
import space.controlnet.lightioc.Container

object Main extends App {
// resolve by type
val foo: Foo = Container.resolve[Foo]
// resolve by string
val str: String = Container.resolve[String]("AString")
// resolve by factory
val bar: Bar = Container.resolve[Bar]
}

自动装配

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import space.controlnet.lightioc.annotation.{ Autowired, Provider }

@Provider
class Foo {
@Autowired
val bar: Bar = null
}

@Provider
class Bar

@Provider
object Baz {
@Autowired
var x: Int = 0 // should be "var"
}

Java API

一个使用Kotlin的例子。

1
2
3
4
5
6
7
8
9
10
11
12
13
import space.controlnet.lightioc.annotation.Singleton
import space.controlnet.lightioc.api.Container

@Singleton
class A {
val x: Int = 100
}

fun main() {
Container.init("<package name>")
val a = Container.resolve(A::class.java)
println(a.x)
}

评论