the blog for developers

Singletons without Singletons: Scala Type Classes

I was using Guice in a project recently. Objects which did not come out of Guice got their dependencies not injected. So I had a global singleton where objects could get their dependencies. Yeah yeah I know singletons are bad and stuff. It would be nicer to let Guice handle it all, but sometimes this is not possible due to framework restrictions where you have no controll over object creation.

For example one part of the project uses UseCase classes and injects depedencies inside them. I want to use those UseCases with

use(new ActivateEmailAddressUseCase(encrypted))

The definition of the use method is simple and looks like this:

object UseCase {
  def use[R](useCase: {def execute(): R}): R = {
    DomainInjector.injector.injectMembers(useCase)
    useCase.execute()
  }
}

where the global DomainInjector looks like this:

object DomainInjector {
  val injector = Guice.createInjector(new GuiceDomain)
  def injectMembers[I](injectee: I) =  injector.injectMembers(injectee)
}

So far so nice. The problem did arise when I was running only parts of the project against sbt ScalaTest testing. Those parts now were coupled to other parts because of the global singleton and I didn’t want to include those other parts as depedencies. Bad. The problem is the GuiceDomain class where dependencies might go to different parts of the application – especially up the hierarchy.

Changing this to an interface implementation

object DomainInjector extends Injector {
  val injector = Guice.createInjector(new GuiceDomain)
  def injectMembers[I](injectee: I) =  injector.injectMembers(injectee)
}

and changing the UseCase class to use an implicit method paramater:

object UseCase {
  def use[R](useCase: {def execute(): R})(implicit injector: Injector): R = {
    injector.injectMembers(useCase)
    useCase.execute()
  }
}

Now the tests could include into their scope

object DummyInjector extends Injector {
  def injectMembers[I](injectee: I) = { }
}

instead of the DomainInjector and still work. Excellent, problem solved.

And if you do not know what this has to do with type classes: I do not know either after reflecting about the blog post 5 minutes after publishing. Sorry for that ;-)

About the author

stephan Stephan Schmidt has been working with internet technologies for the last 20 years. He was head of development, consultant and CTO and is a speaker, author and blog writer. He specializes in organizing and optimizing software development helping companies by increasing productivity with lean software development and agile methodologies. Want to know more? All views are only his own. You can find him on Google +

You can leave a Reply here. Of course, you should follow me on twitter here.

You can share this post!
Do you want to tell others about this article? Use the social bookmark icons to submit this artice to the service of your choice. Thanks.

14 Tweets

Leave a reply.

Comments

With a type conversion you could have reversed the method calls from

use(new ActivateEmailAddressUseCase(encrypted))

to

new ActivateEmailAddressUseCase(encrypted).use()

which is a bit nicer. We have to leave the static import Java style behind mentally. Although Lists.newArrayList() is nice. :-)

@Thomas: I’m not sure I like .use() better actually :-)

Oh me, too:

import static String._;

toUpperCase(substring(s, 1, 2));

is so much better than

s.substring(1,2).toUpperCase();

I always prefered this style. :-)

_efwe_

“”
but sometimes this is not possible due to framework restrictions where you have no controll over object creation
“”

100% agreed. thats why there is a paragraph abaout ‘Glue code and the evil singleton’ in the springframework documentation for years now.

i used to call this IIOC – inversion of inversion of control :-)

@_efwe_ :-)

nuttycom

Can you elaborate a bit on not having any control over object creation? Injector.injectMembers seems like a serious code smell to me – what is the situation where you actually need to use this?

Leave a Reply

What people wrote somewhere else:

Just blogged “Singletons without Singletons: Scala Type Classes” http://bit.ly/a3AkvD

This comment was originally posted on Twitter

RT @codemonkeyism: Just blogged “Singletons without Singletons: Scala Type Classes” http://bit.ly/a3AkvD

This comment was originally posted on Twitter

RT @codemonkeyism: Just blogged “Singletons without Singletons: Scala Type Classes” http://bit.ly/a3AkvD

This comment was originally posted on Twitter

Stephan Schmidt: Singletons without Singletons: Scala Type Classes http://bit.ly/bmXEl7

This comment was originally posted on Twitter

RT @codemonkeyism Just blogged “Singletons without Singletons: Scala Type Classes” http://bit.ly/a3AkvD

This comment was originally posted on Twitter

RT @codemonkeyism: Just blogged “Singletons without Singletons: Scala Type Classes” http://bit.ly/a3AkvD

This comment was originally posted on Twitter

RT @codemonkeyism Just blogged “Singletons without Singletons: Scala Type Classes” http://bit.ly/a3AkvD

This comment was originally posted on Twitter

Code Monkeyism: Singletons without Singletons: Scala Type Classes http://ff.im/-pB141

This comment was originally posted on Twitter

RT @PlanetScala: Stephan Schmidt: Singletons without Singletons: Scala Type Classes http://bit.ly/bmXEl7

This comment was originally posted on Twitter

RT @codemonkeyism Just blogged “Singletons without Singletons: Scala Type Classes” http://bit.ly/a3AkvD

This comment was originally posted on Twitter

RT @aloiscochard: RT @codemonkeyism Just blogged “Singletons without Singletons: Scala Type Classes” http://bit.ly/a3AkvD

This comment was originally posted on Twitter

Code Monkeyism: Singletons without Singletons: Scala Type Classes http://ff.im/-pEMsL

This comment was originally posted on Twitter

[Scala] Singletons without Singletons: Scala Type Classes: I was using Guice in a project recently. Objects which … http://bit.ly/9xhcmJ

This comment was originally posted on Twitter

Singletons without Singletons: Scala Type Classes http://bit.ly/dmCsv2

This comment was originally posted on Twitter

Additional comments powered by BackType

Guide to CodeMonkeyism

Over the last 4 years I wrote many articles on this blog. To make it easier for you to find the relevant ones, I've organized them into topics.

Top 10

6 reasons why my VC funded startup did fail

Go Ahead: Next Generation Java Programming Style

Java Interview questions: Write a String Reverser

The dark side of NoSQL

7 Bad Signs not to Work for a Software Company or Startup

Is Java dead?

Scala vs. Clojure

Never, never, never use String in Java

No future for functional programming in 2008 – Scala, F# and Nu

Clojure vs Scala, Part 2

Java Developer

Is Java Dead?

Go Ahead: Next Generation Java Programming Style

Be careful with magical code

All variables in Java must be final

Never, never, never use String in Java

Bending Java: More readable code with methods that do nothing?

NoSQL Guy

NoSQL: The Dawn of Polyglot Persistence

The dark side of NoSQL

Essential storage tradeoff: Simple Reads vs. Simple Writes

Sharding destroys the goals of your relational database

The unholy legacy of databases

Startup/CTO

Development Dream Teams

6 reasons why my VC funded startup did fail

American vs. European style of Software Development

12 Things to Reduce Your Lead Time and Time to Market

The high cost of overhead when working in parallel

Essential storage tradeoff: Simple Reads vs. Simple Writes

Job Seeker

Another Good (Java) Interview Question

7 Bad Signs not to Work for a Software Company or Startup

Java Interview questions: Write a String Reverser (and use Recursion!)

Java Interview questions: Multiple Inheritance

As a Manager: What I value in developers

Top 10 Tips (+1) to Get a Pay Raise

Agilist

What Developers Need to Know About Agile

5 Practices Better to Change in Your Scrum Implementation

Scrum is not about engineering practices

ScrumMaster and ZenMaster: The joke of certification

What is Trans-Scrum?