21

Are there any existing modern-day programming languages that explicitly have dependency injection as a language feature, and if so, are there any examples of how such programming languages use their syntax to separate program dependencies from their concrete implementations?

(Please Note: I'm not looking for an DI/IOC framework--I'm actually looking for a programming language that actually has this feature built into the language).

Brandon
  • 16,382
  • 12
  • 55
  • 88
plaureano
  • 3,139
  • 6
  • 30
  • 29

4 Answers4

13

You won't find dependency injection as a language feature, as it's generally seen as a design pattern. Design patterns arise as workarounds for missing language features - for example if you have first class types as a language feature you don't need the factory pattern ( see p12 of Norvig's presentation ), if you have multi-methods as a language feature you don't need the double dispatch pattern.

The language feature for which DI is the design pattern is "parametric modules". See the discussion of modules vs DI relating to Gilad Bracha's language Newspeak

Pete Kirkham
  • 48,893
  • 5
  • 92
  • 171
  • 4
    And see also the discussion on "Design Patterns are Signs of Weakness in Programming Languages" -- http://www.oreillynet.com/onlamp/blog/2006/10/design_patterns_are_signs_of_w.html – avandeursen Oct 03 '09 at 08:55
  • Some languages *do* provide a service locator as a langauge feature. For example, python. – Arafangion Jan 26 '11 at 09:02
  • @Arafangion you mean the import statement http://docs.python.org/reference/index.html, or something else in the language (as opposed to a library)? Having a search path for modules is quite a lot less than service location, and dependency injection does not equal service location. – Pete Kirkham Jan 26 '11 at 18:35
  • You can change the contents of a module at runtime (at any time), and the changes will affect every module that imports it. This is much the same as telling the service locator "If requested for an IFoo, provide a Bar instead of the usual Foo". – Arafangion Jan 26 '11 at 21:35
  • @Arafanngion Same has been true of many other runtimes. What service discovery normally gives you is a means of selecting between alternatives based on criteria, whereas if two providers attempt to monkey patch the same module it's hard to see any modular resolution. – Pete Kirkham Jan 27 '11 at 22:41
  • 2
    "if you have first class types as a language feature you don't need the factory pattern" any example or proof of this theory? – Kamil Dziedzic Apr 14 '16 at 14:00
  • @KamilDziedzic page 12 of the presentation – Pete Kirkham Apr 14 '16 at 14:55
  • I can't find much information online about parametric modules. Is this present in ML's module system? As a side-note, something which seems to do DI as a language feature is Haskell's yet-to-be-implemented backpack. – Cameron Martin Jun 14 '16 at 07:48
  • @CameronMartin I got my information form NewSpeak. I'm not familiar with ML – Pete Kirkham Jun 14 '16 at 07:50
4

I don't mean to sound like a jerk, but every OO language supports dependency injection. No special syntax is required. Just construct your object with their dependencies (or set their dependencies later).

You can actually wire up all your dependencies somewhere near the top of the program - not necessarily main(), but close to the top.

Daniel Yankowsky
  • 6,956
  • 1
  • 35
  • 39
  • 3
    I'm not looking for a programming language that lets you implement dependency injection, I'm actually looking for a language that says "I want to create an IFoo" and then the compiler/runtime decides what gets created without specifying the concrete classes at compile time. – plaureano Oct 04 '09 at 05:05
  • Ah, I think you're looking for language support for autowiring or auto service discovery. My mistake. – Daniel Yankowsky Oct 04 '09 at 18:27
  • you mean "inversion of control"? you don't even need OO for that, can just write every module as a functor/factory and initialize them in the composition root I suppose? "Dependency injection" is when you don't have to manually (write code to/in your brain) traverse the dependency graph and initialize them in the right order, instead, some framework figures that out for you. I guess IoC is a more important thing to have than DI, which is just a convenient way to do It. However, your composition roots could get pretty big that is when you need DI. – Harry Jun 12 '18 at 03:21
  • What you're describing is commonly called a "dependency injection framework", i.e. a framework which does dependency injection. But manual dependency injection is also a thing. Inversion of control is a broader topic that also comprises things like event callbacks. – Daniel Yankowsky Aug 02 '18 at 14:06
3

Noop supposedly does this, but I haven't seen the language specification (my patience ran out before I found it).

starblue
  • 55,348
  • 14
  • 97
  • 151
  • 1
    The injection proposal for noop is discussed at http://code.google.com/p/noop/wiki/Features and http://code.google.com/p/noop/wiki/ProposalForNewableVsInjectable The proposal for noop injection support will be based on Google's Guice framework for injection. http://code.google.com/p/google-guice/ – avandeursen Oct 03 '09 at 08:05
  • It looks like Noop is a dead language. There hasn't been any activity in the Noop language forum for quite a while now. – plaureano Jun 30 '10 at 22:44
2

One could say that Scala supports dependency injection out of the box with the help of traits and self-type annotations. Take a look on a Cake Pattern:

http://jonasboner.com/2008/10/06/real-world-scala-dependency-injection-di/

Basically, this approach uses traits with declared dependencies (by using self-types) to let the compiler do the work of wiring them together.

This is the declaration registry:

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

...registering the user repository:

trait UserRepositoryComponent {
  val userRepository: UserRepository

  class UserRepository {
    ...
  }
}

...and the user service component that depends on the repository:

trait UserServiceComponent { 
  this: UserRepositoryComponent => 

  val userService: UserService  

  class UserService {
    ... 
  }
}
Piotr Trzpil
  • 282
  • 2
  • 12
  • +1 For Scala. Check out the AWESOME talk, [Dead-Simple Dependency Injection](http://www.youtube.com/watch?v=ZasXwtTRkio) Runar is super-smart, and also hilarious: "Inversion of Control, which is really just a pretentious way of saying 'taking an argument'" – CrazyPyro Aug 12 '14 at 01:52