Implicits for dependency injection vs. cake pattern vs. Guice

5,065 views
Skip to first unread message

Luke Vilnis

unread,
May 2, 2012, 3:14:44 PM5/2/12
to scala-user
I find myself using dependency injection (in non-Scala languages) for fairly simple things like managing singletons, keeping services fine-grained, and instantiating objects without needing an explicit copy of all their dependencies. I also use it to mock up stub services for integration and unit tests. It seems like this sort of use case for DI (singleton only, no need for factories or xml configuration or what have you) should be easily served by implicits.

I'm talking about something simple like this:

class Foo(val x: Bar, val y: Baz)(implicit val svc: FooService) {
  ...
}

object ProductionContainer {
  implicit val productionFooService: FooService = ...
}

object TestingContainer {
  implicit val testingFooService: FooService = ...
}

object Tests {
  import TestingContainer._
  ...
  val testFoo = new Foo(someBar, someBaz)
}

object Main {
  import ProductionContainer._
  ...
  val prodFoo = new Foo(someBar, someBaz)
}

I haven't seen too much about this approach being used specifically for dependency injection. Is there anything I'm missing, or is this a viable approach for dependency injection that focuses mainly on singleton services? Even better, is there some sort of comparison article between the cake pattern and implicit approaches to DI in Scala (or even Guice/etc)?

PS. How would you extend this approach to nested containers? I kinda have a feeling implicits don't work that way, at least not obviously.

Ken Scambler

unread,
May 4, 2012, 12:43:08 AM5/4/12
to Luke Vilnis, scala-user
Using implicits suffers from the normal disadvantages of manually threading dependencies through constructors, which is that if something 5 layers deep needs a new thing, then you need to add a new parameter to everything on the way down.   The logical end-point looks like an upside-down pyramid where your top-level classes have everything under the sun in their parameter list.

Furthermore, the clarity/concision tradeoff of using implicits here is not at all compelling; it's hiding information that a maintenance programmer really wants and needs to see.  You would need to put implicit value declarations all over the place, whose purpose might not be apparent to someone unaware of the implicit-needing behaviour of the downstream dependencies. 

That said, I think there are people that do it this way; Jonas Boner mentions this technique in his famous blog post on the Cake Pattern.

Ken

Luke Vilnis

unread,
May 4, 2012, 1:52:24 AM5/4/12
to Ken Scambler, scala-user
Yeah, I started doing some experimenting, and I was not impressed with implicits for DI. The basic problem seems to be that you want the "container scope" introduced by dependency injection to be dynamic, but implicit scope is lexical (static). So if a class A doesnt depend on a service S, then it can't instantiate a class B that does, without annoyingly requiring a reference to S for no other reason than to pass it through. This pretty much defeats (one of) the entire point(s) of dependency injection, which is to allow objects to be instantiated without having/needing access to all of their dependencies.

I started work on a very lightweight DI framework for Scala, suitable only for managing singletons (which is all I use DI for anyhow), that uses only constructor injection and borrows a nice type-safety idea that I've seen elsewhere. It's not optimized at all, but the basic idea is, you put all of the singletons a class requires as arguments at the end of its constructor, and then you implement a marker trait/typeclass that indicates how many of your constructor arguments are from the container and which must be passed in. The marker interface also allows for type-safety in that instantiating the object requires passing the correct number and types of arguments.

Here's an example use, with parenting containers and nested construction (Constructable is the marker type class):

  trait FooService { def serve: String }
  trait ProdFooService extends FooService { def serve = "Production!" }
  trait DevFooService extends FooService { def serve = "Development!" }
  trait BarService { def serve = "Bar!" }

  .... container / marker implementation here ...

  implicit object DooJammerConstructable extends Constructable2[DooJammer, String, Int] { }
  implicit object WhimwhamConstructable extends Constructable[Whimwham] { }

  class DooJammer(
    val x: String,
    val y: Int,
    val fooService: FooService,
    val barService: BarService,
    val container: DependencyInjectionContainer) {
    def frob(): Unit = println("%s, %s, %s, %s" format (x, y, fooService.serve, barService.serve))
    def wobble(): Unit = container.create[Whimwham].frob()
  }
  class Whimwham(val fooService: FooService) {
    def frob(): Unit = println("Hello, %s" format fooService.serve)
  }

  def main(args: Array[String]): Unit = {
    val parentContainer = new DependencyInjectionContainerImpl(None)
    parentContainer.registerSingleton[FooService](new DevFooService { })
    parentContainer.registerSingleton[BarService](new BarService { })
    parentContainer.create[DooJammer, String, Int]("asdasd", 12).frob()

    val container2 = new DependencyInjectionContainerImpl(Some(parentContainer))
    container2.registerSingleton[FooService](new ProdFooService { })
    val dooJammer2 = container2.create[DooJammer, String, Int]("asdasd", 12)
    dooJammer2.frob()
    dooJammer2.wobble()
  }

Among other issues, it would be nice to not have to specify all the argument types when calling create. If interested, you can find the very rough first cut here (it's really more like a Gist than anything).

pagoda_5b

unread,
May 4, 2012, 5:52:07 AM5/4/12
to scala...@googlegroups.com, Ken Scambler
I suggest you take a peek at Dick Wall's subcut injection framework, which started pretty much from the same considerations as yours:  https://github.com/dickwall/subcut

Another purely functional alternative is using typeclasses and the Reader Monad, possibly using Scalaz

For both solutions you can find explanatory videos from different conferences just searching the internet (e.g. 
and 

Kevin Wright

unread,
May 4, 2012, 6:00:00 AM5/4/12
to pagoda_5b, scala...@googlegroups.com, Ken Scambler
For what it's worth...

You can see the implicit injection approach used to great effect in Akka 2.0. In particular, it's used for passing around ActorSystem references and has lead to a very clean design.

--
Kevin Wright
mail: kevin....@scalatechnology.com
gtalk / msn : kev.lee...@gmail.com
vibe / skype: kev.lee.wright
steam: kev_lee_wright

"My point today is that, if we wish to count lines of code, we should not regard them as "lines produced" but as "lines spent": the current conventional wisdom is so foolish as to book that count on the wrong side of the ledger" ~ Dijkstra

Robert Wills

unread,
May 4, 2012, 9:53:26 AM5/4/12
to scala...@googlegroups.com
Also worth looking at sindi:
http://aloiscochard.github.com/sindi/

I've only just discovered it, but at first blush it looks interesting.

Yung-Lin Ho

unread,
May 6, 2012, 1:39:02 AM5/6/12
to scala...@googlegroups.com, Ken Scambler

I have surveyed few DI options and in the end, I chose to use constructor injection with JSR-330. 

Subcut looks nice but it has one big issue in the design. Martin Fowler described this issue as `Service Locator`_ in his article. The Problem of Service Locator is that you give all the control you earned in IoC back to the dependent object. You pass all components to the dependent object in a map/module and let the dependent object to pick whatever components it wants from the map. I won't call this 'Inversion of Control'. 

Also, unlike constructor injection or cake pattern, when using Service Locator, it is hard to figure out what components are required by X service without  going through the source code of X Service.

This is why I won't use any Service Locator based DI framework.


The Reader Monad also suffer from the same pyramid issue Ken described earlier in this thread. When pushing injection as late as possible, the top level object has to provides all components to the middle and lower level objects. In the end, you will have to change the middle level classes when introducing new component to the application. Or, you will put all components in a Map/Module/Service locator and pass this map everywhere.

Ken Scambler

unread,
May 6, 2012, 6:59:43 AM5/6/12
to Kevin Wright, pagoda_5b, scala...@googlegroups.com
On 4 May 2012 20:00, Kevin Wright <kev.lee...@gmail.com> wrote:
For what it's worth...

You can see the implicit injection approach used to great effect in Akka 2.0. In particular, it's used for passing around ActorSystem references and has lead to a very clean design.

I had a very quick look in the Akka source and I couldn't find any good examples -- am I right in assuming that the whole framework is not wired together in this way, and it is more a way of sharing a particular context object which is of limited interest to the API's users?

I think Iterable#sum is a great example of a well-chosen tradeoff, and I'm guessing ActorSystem is along these lines, but I can't see using this technique pervasively to wire together application modules being a good thing.

Ken Scambler

unread,
May 6, 2012, 7:30:14 AM5/6/12
to Kevin Wright, scala-user
On 6 May 2012 21:14, Kevin Wright <kev.lee...@gmail.com> wrote:

Iterable#sum is a slightly different beast. It's a type class, and not quite dependency injection as you would normally understand the concept.

True -- it's relevant inasmuch as its a "thing that some code needs to get from somewhere", and it's a good use-case of an implicit for this purpose. 

I was wondering about how pervasively Akka uses implicits for DI, and how ActorSystem fits in, because I'm sceptical about implicit constructor-injection's advantages over explicit in general usage.

Luke Vilnis

unread,
May 6, 2012, 1:18:21 PM5/6/12
to Yung-Lin Ho, scala...@googlegroups.com, Ken Scambler
Exactly. Once I started using constructor injection, I couldn't go back to pulling services out of a dictionary. It's really not much better than statics/singletons at that point because you lose the ability to tell the dependencies of an object just by reading its constructor signature - instead you have to hunt through the implementation, not just the interfaces at the boundary.

I actually hadn't seen JSR-330 before (such a Java noob), this looks the closest so far to what I want. It looks like if you want to pass in values from the user, you use two constructors, one for the user to invoke and one that is automatically invoked by the container?

Roland Kuhn

unread,
May 7, 2012, 3:01:19 AM5/7/12
to Ken Scambler, Kevin Wright, pagoda_5b, scala...@googlegroups.com
Akka is not wired together from components in that way, so you are right in not finding examples. We do use implicits for dependency injection of a different kind: the users of our API may provide some of the arguments implicitly (in those cases where lexically scoped values of a certain type like “Timeout” or “ExecutionContext” make sense). This makes user code easier to read because of less clutter. On the other hand we keep importable default values close-by (like “import context.dispatcher”, which gives you an implicit ExecutionContext).

This way, implicits make DI into our tooling nicer for users. What else do you need? (PS: we removed all singletons from the code base, just sayin’ …)

Regards,

Roland Kuhn
Typesafe – The software stack for applications that scale.
twitter: @rolandkuhn


√iktor Ҡlang

unread,
May 7, 2012, 4:01:41 AM5/7/12
to Roland Kuhn, Ken Scambler, Kevin Wright, pagoda_5b, scala...@googlegroups.com
The implicit-propagation of "sender" is DI
--
Viktor Klang

Akka Tech Lead
Typesafe - The software stack for applications that scale

Twitter: @viktorklang

Reply all
Reply to author
Forward
0 new messages