Alf Kristian StøyleKnow IT Objectnet
Hvordan vi klarte oss uten Spring,dependency injection i Scala
Dependency Injection
Transactions
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
http://jonasboner.com/2008/10/06/real-world-scala-dependency-injection-di.html
http://lamp.epfl.ch/~odersky/papers/ScalableComponent.pdf
case class User(username: String, password: String)
class UserRepository { def authenticate(user: User): User = { println("authenticating user: " + user) user } def create(user: User): User = { println("creating user: " + user) user }}
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))}
class UserRepository { def authenticate(user: User): User = { println("authenticating user: " + user) user } def create(user: User): User = { println("creating user: " + user) user }}
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 } } }
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))}
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
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
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)
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)
Gotchas
• Class vs Object
• Typenavn
Andre måter
• Structural types
• Implicit declarations
• Functional currying
• Spring
• Guice
Transactions
import org.springframework.transaction.annotation.Transactional
class UserService { @Transactional def create(username: String, password: String) = { userRepository.create(new User(username, password)) }}
Transactions
import TransactionManager._
class UserService { def create(username: String, password: String) = transactional { userRepository.create(new User(username, password)) }}
object TransactionManager { def transactional[A](work: => A): A = ...}
Scala DI
http://jonasboner.com/2008/10/06/real-world-scala-dependency-injection-di.html
http://programming-scala.labs.oreilly.com/ch13.html#DependencyInjectionInScala
http://debasishg.blogspot.com/2011/03/pushing-envelope-on-oo-and-functional.html
[email protected]://slideshare.net/stoyle/di-scalahttp://github.com/stoyle/di-scala
Top Related