Dependency injection and subclassing


#1

Hello,

Today I was working on converting a single class into a series of subclasses that share some common behavior, then I encountered an issue with injected dependencies that seems to be not inherited through class extension.

Here is a summary of my tests. Please note that file/factory names are camel cased in this example to make them more readable, but were not in the tests.

Basis. Works when calling method foo from /myType/myClass instances

in /myType/myClass.js

import Ember from "...";
export default Ember.MyEmberSuper.extend({
  foo(){
    this.get("myInjectedDependencyName").someMethod();
  }
}


in /initializers/myDepencyType-myDependency.js

import MyDependency from "...";
export function initialize(application) {
  application.register("myDependencyType:myDependency", MyDependency);
  application.inject("myType:myClass", "myInjectedDependencyName", "myDependencyType:mydependency");
}
export default {
  name: "mydependency",
  initialize: initialize
};

Converting to parent class with injected dependency, and subclass. Works when calling method foo from myParentClass instances, does not work when calling foo from mySubClass instances: this.get(“myInjectedDependencyName”) returns undefined

in /myType/myParentClass.js

import Ember from "...";
export default Ember.MyEmberSuper.extend({
  foo(){
    this.get("myInjectedDependencyName").someMethod();
  }
}

in /myType/mySubClass.js

import MyParentClass from "my-app/mytype/myParentClass"
export default MyParentClass.extend({
  ... (other stuff, does not overload method foo nor property myInjectedDependencyName)
}

in /initializers/myDepencyType-myDependency.js

import MyDependency from "...";
export function initialize(application) {
  application.register("myDependencyType:myDependency", MyDependency);
  application.inject("myType:myParentClass", "myInjectedDependencyName", "myDependencyType:mydependency");
}
export default {
  name: "mydependency",
  initialize: initialize
};

Class definitions does not change, but now we inject the dependency in both myParentClass and mySubClass. Calling method foo from parent and sub both work

in /initializers/myDepencyType-myDependency.js

import MyDependency from "...";
export function initialize(application) {
  application.register("myDependencyType:myDependency", MyDependency);
  application.inject("myType:myParentClass", "myInjectedDependencyName", "myDependencyType:mydependency");
  application.inject("myType:mySubClass", "myInjectedDependencyName", "myDependencyType:mydependency");
}
export default {
  name: "mydependency",
  initialize: initialize
};

Conclusion

To me, it looks like properties injected into a class are not propagated properly to the subclasses that extend it. Did I make a mistake somewhere, or is it an intended behavior ?

If that is an intended behavior, what is its purpose ? I find it annoying that it requires to repeat the injection code for all subclasses, or to inject for the whole factory type to avoid repetitions.