您不需要(快速)依赖注入框架

Scala中有Cake Design Pattern来进行依赖注入(DI),还有一个称为Minimal Cake Design Pattern的最小版本。

我们实际上并不需要在Swift中进行DI的框架。 仅使用纯Swift代码,我将向您介绍如何使用最小蛋糕设计模式在生产和测试代码上进行DI。

每个类都需要接口和实现

对于每个类,我将使用协议创建一个以Uses…开头的接口 并使用以MixIn…开头的类创建一个Implementation

接口仅声明协议可以做什么,而实现则声明如何

协议UserRepository { 
func findById(id:Int)->用户?
}
  //接口 
协议UsesUserRepository {
var userRepository:UserRepository {get}
}
//实现
类MixInUserRepository:UserRepository {
func findById(id:Int)->用户? {
返回用户(id:id,名称:“ orakaro”,角色:“ member”)
}
}

UserRepository的实例被另一个类(例如UserService)使用时,我将使用上述Interface来声明新的配对协议/扩展,当然还要声明UserService本身的另一个Interface和Implementation。

听起来比它复杂。 让我们看一下代码。

 协议UserService:UsesUserRepository { 
func Promotion(asigneeId:Int)->用户?
}
扩展UserService {
func Promotion(asigneeId:Int)->用户? {
Guard var asignee = userRepository.findById(id:asigneeId)else {返回nil}
asignee.role =“领导者”
返回受让人
}
}
  //接口 
协议UsesUserService {
var userService:UserService {获取}
}
//实现
类MixInUserService:UserService {
让userRepository:UserRepository = MixInUserRepository()
}

如果UserService被另一个TeamService再次使用怎么办? 很好地应用了相同的逻辑,使用UsesUserService声明一对协议/扩展,并且新服务也将具有接口/实现。

 协议TeamService:UsesUserService { 
func buildTeam(领导者:用户)-> [用户?]
}
扩展TeamService {
func buildTeam(领导者:用户)-> [用户?] {
返回[userService.promote(asigneeId:Leader.id)]
}
}
  //接口 
协议UsesTeamServvice {
var teamService:TeamService {get}
}
//实现
类MixInTeamService:TeamService {
让userService:UserService = MixInUserService()
}

所有此类接线均为静态类型。 如果缺少依赖项声明或拼写错误,则会出现编译错误。 此外,实现是不可变的(声明为let )。

应用程序使用实现

例如,我们使用TeamService的应用程序可以像这样

 让applicationLive = MixInTeamService() 
让团队= applicationLive.buildTeam(领导者:用户(标识:1,名称:“ orakaro”,角色:“成员”))
print(team)// [可选(用户(id:1,名称:“ orakaro”,角色:可选(“ leader”)))]

DI使用接口

目前, 即使没有模拟框架,我们也可以模拟存储库注入UserService来测试提升方法。 我们不仅在创建模拟,而且将我们创建的模拟作为声明的依赖项(无论定义在何处)进行连接。

 类MockUserRepository:UserRepository { 
func findById(id:Int)->用户? {return nil}
}
类UserServiceForTest:UserService {
让userRepository:UserRepository = MockUserRepository()
}
让testService = UserServiceForTest()
print(testService.promote(asigneeId:1))//无

可以使用相同的方式注入TeamService来测试buildTeam方法。

 类TeamServiceForTest:TeamService { 
让userService:UserService = UserServiceForTest()
}
让applicationTest = TeamServiceForTest()
让testTeam = applicationTest.buildTeam(领导者:用户(id:1,名称:“ orakaro”,角色:“ member”))
print(testTeam)// [无]

现在的大局是:

有关更多详细信息,请参见Github上的操场。

加起来

我发现此解决方案是一种构造Swift代码和创建对象图的简单明了的方法。 它仅使用纯Swiftprotocol /扩展,不依赖于任何框架或库,并提供编译时检查以确保所有内容均已正确定义。

Interesting Posts