21
Alf Kristian Støyle Know IT Objectnet Hvordan vi klarte oss uten Spring, dependency injection i Scala

Dependency injection in Scala

Embed Size (px)

DESCRIPTION

Dependency injection in Scala done without any frameworks.

Citation preview

Page 1: Dependency injection in Scala

Alf Kristian StøyleKnow IT Objectnet

Hvordan vi klarte oss uten Spring,dependency injection i Scala

Page 2: Dependency injection in Scala

Dependency Injection

Transactions

Page 3: Dependency injection in Scala

Cake pattern‘Cake Pattern’ because “(...) beyond my

appreciation of cake, [a] cake is made of a number of layers (separated by jam), and

can be sliced. The layers represent the different levels of inner class nesting. It is

conceivable that you would reach the bottom layer by working your way down

from the top.

http://scala.sygneca.com/patterns/component-mixins

Page 5: Dependency injection in Scala

case class User(username: String, password: String)

Page 6: Dependency injection in Scala

class UserRepository { def authenticate(user: User): User = { println("authenticating user: " + user) user } def create(user: User): User = { println("creating user: " + user) user }}

Page 7: Dependency injection in Scala

class UserService {

val userRepository = new UserRepository

def authenticate(username: String, password: String): User = userRepository.authenticate(new User(username, password)) def create(username: String, password: String): User = userRepository.create(new User(username, password))}

Page 8: Dependency injection in Scala

class UserRepository { def authenticate(user: User): User = { println("authenticating user: " + user) user } def create(user: User): User = { println("creating user: " + user) user }}

Page 9: Dependency injection in Scala

trait UserRepositoryComponent {

val userRepository: UserRepository class UserRepository { def authenticate(user: User): User = { println("authenticating user: " + user) user } def create(user: User): User = { println("creating user: " + user) user } } }

Page 10: Dependency injection in Scala

class UserService { def authenticate(username: String, password: String): User = userRepository.authenticate(new User(username, password)) def create(username: String, password: String): User = userRepository.create(new User(username, password))}

Page 11: Dependency injection in Scala

trait UserServiceComponent {

val userService: UserService

class UserService { def authenticate(username: String, password: String): User = userRepository.authenticate(new User(username, password)) def create(username: String, password: String): User = userRepository.create(new User(username, password)) } }

//val userRepository: UserRepository

extends UserRepositoryComponent

Page 12: Dependency injection in Scala

trait UserServiceComponent { self: UserRepositoryComponent =>

val userService: UserService

class UserService { def authenticate(username: String, password: String): User = userRepository.authenticate(new User(username, password)) def create(username: String, password: String): User = self.userRepository.create(new User(username, password)) } }

//val userRepository: UserRepository

Page 13: Dependency injection in Scala

object ComponentRegistry extends UserServiceComponent with UserRepositoryComponent { val userRepository = new UserRepository val userService = new UserService }

val userService = ComponentRegistry.userService val user = userService.authenticate("user", "password")// => User(user,password)

Page 14: Dependency injection in Scala

import org.mockito.Mockito._

class TestingEnvironment extends UserServiceComponent with UserRepositoryComponent { val userRepository = mock(classOf[UserRepository]) val userService = new UserService }

val testEnv = new TestingEnvironmentwhen(testEnv.userRepository .authenticate(new User("user", "password"))) .thenReturn(new User("mock", "mockpwd"))val userService = testEnv.userServiceval user = userService.authenticate("user", "password")// => User(mock,mockpwd)

Page 15: Dependency injection in Scala

Gotchas

• Class vs Object

• Typenavn

Page 16: Dependency injection in Scala

Andre måter

• Structural types

• Implicit declarations

• Functional currying

• Spring

• Guice

Page 17: Dependency injection in Scala

Transactions

import org.springframework.transaction.annotation.Transactional

class UserService { @Transactional def create(username: String, password: String) = { userRepository.create(new User(username, password)) }}

Page 18: Dependency injection in Scala

Transactions

import TransactionManager._

class UserService { def create(username: String, password: String) = transactional { userRepository.create(new User(username, password)) }}

Page 19: Dependency injection in Scala

object TransactionManager { def transactional[A](work: => A): A = ...}