0

preface - this is more a conceptual discussion rather than a "how-to". If there is a simple way to implement, then I would certainly be thankful for tips on how but I really want to gain insight on why/why not this isn't possible or a good idea. Any and all comments/constructive criticism is welcome.

property/setter-based dependency injection

new $injector APIs

# pseudo-code

postInjectionHook = 'init'

injectInto = (target)->
    for key of target
       if $injector/this.$has key
           target[key] = $injector.get key

    if target[postInjectionHook] is Function
        target[postInjectionHook]()

simple controller example

angular.module 'app', []
.controller, 'SomeController', class SomeController

  $http: undefined
  $q: undefined

  init: -> #do some work after we get our dependencies

elsewhere in angular-land

uiController = new SomeController
$injector.injectInto uiController

why?

I love the simplicity of javaScript. It's a very malleable, yet powerful language. However I don't think I'm the only developer that came from another programming language longing for certain features missing from javascript. As such, I utilize inheritance (I know OMG!!!) to structure many base-classes in my application development. Specifically all of my angular controllers inherit from key base classes (e.g. baseViewController, basePopupController, etc.).

Angular's forcing of constructor-based DI makes inheritance somewhat of a pain if I plan to extend beyond the base controller classes. The constructor arguments must be carried over to any subclasses. I wish there were a way to allow different types of dependency injection.

jusopi
  • 6,791
  • 2
  • 33
  • 44
  • I personally don't see the need for this. I find that I can do a heck of a lot by simply _reusing_ Controllers, then using composition to add whatever custom functionality I need (via directives or adding small subcontrollers with ng-controller). Composition over inheritance FTW! – Amy Blankenship Nov 02 '15 at 17:53
  • Setter-based dependency injection is a euphemism for creating unusable instances. Having said that using a factory you are free to inject the dependencies any way you want it. – a better oliver Nov 02 '15 at 17:57
  • @zeroflagL I certainly have read that myself and can see why some argue that case. However the `postInjectionHook` callback on the injection target would be a safeguard against missing dependencies. Regarding your factory comment, can you provide a simple example? Would I use `module.factory` instead of `module.controller`? – jusopi Nov 02 '15 at 18:11
  • I figured the `pseudo-code` comment would suffice. Added coffeescript tag. – jusopi Nov 02 '15 at 18:24
  • You certainly rely on coffee class implementation for inheritance and this creates the context. I'm not sure how it differs from ES7/TS, but dependency inheritance [is not a problem there](http://stackoverflow.com/questions/33313849/class-level-injectable-dependencies-in-angular-1-x-using-typescript/33315799#33315799). I'm not sure if modified $injector can solve any problems that cannot be solved otherwise, but it can certainly create them: testing, uninjecting inherited dependencies, etc. – Estus Flask Nov 02 '15 at 18:39
  • 1
    According to your code the `postInjectionHook` will be called _after we get our dependencies_ so it cannot be a safeguard. On the other hand it's JavaScript and you can call a constructor without arguments and thereby create an unusable instance as well ;) Anyway, implementing your approach shouldn't be much of an effort. It should be enough to modify `invoke()`, I guess, which incidentally could be regarded as factory. You will, however, have to mark your classes somehow so that other code that relies on constructor injection (all of Angular e.g.) won't stop working. – a better oliver Nov 02 '15 at 19:58

0 Answers0