-
Notifications
You must be signed in to change notification settings - Fork 56
Injecting Dependencies
Next, let's take a look at how the Deft JS IoC container is used. Consider the MainViewController
class we just created. Recall that in my IoC configuration, I had set up a dependency provider for the CompanyStore
class named companyStore
. If I wanted to use the CompanyStore
object in MainViewController
, all I need to do is specify the name of that dependency provider using the inject
property, like this:
Ext.define("DeftQuickStart.controller.MainController", {
extend: "Deft.mvc.ViewController",
inject: ["companyStore"],
config: {
companyStore: null
},
init: function() {
return this.callParent(arguments);
}
});
In the above example, I'm also setting up a config value for
companyStore
, so that Ext JS will create a getter and setter for that property. This is optional, but it's good practice.
When Deft JS finds an inject
property in one of your classes, it goes and looks for a corresponding dependency provider in the IoC configuration. If it finds one, it creates a singleton instance of the dependent class (if it hasn't already been created), and then resolves the dependency by populating the target property with the dependent object. So in this case, DeftJS will create an instance of CompanyStore
and set it into the companyStore
property of my MainViewController
. All of this happens automatically, using class preprocessors.
Again, there are some more advanced IoC configuration options that allow you to specify a dependency provider as a singleton or a prototype object, as well as controlling lazy vs. eager creation of dependency providers. We'll look at these options a bit later.
DeftJS handles the injections and resolves the dependencies before the constructors of your classes run. That means the injected dependencies are available for use even in your constructors!
Folks with some experience using the Sencha platform might have noticed that I didn't specify the CompanyStore
class in a requries
property in the MainViewController
. That's because I don't need to. DeftJS takes care of making sure the dependent class file is registered with ExtJS as being required.
You can specify an inject
property on any of your classes. So ViewControllers
, models, and view classes can all have dependencies injected into them. You can even inject dependencies into other dependency providers. In other words, if you have a CompanyService
class and a CompanyStore
class set up as dependency providers, the CompanyService
class could specify companyStore
in its inject
tag. This would inject the CompanyStore
into the CompanyService
. So you can build up entire hierarchies of dependencies if you need to.
Beware Circular Dependencies: The only major caveat on injecting dependencies into other dependency providers is to watch out for circular dependencies. If
DependencyA
tries to injectDependencyB
, butDependencyB
wantsDependencyA
injected, we run into a "chicken-and-egg" problem.
As you may have noticed, by default DeftJS tries to inject the dependency into a property with the same name as the dependency provider. If you need to inject it into a different property, you can do that too:
Ext.define("DeftQuickStart.controller.MainController", {
extend: "Deft.mvc.ViewController",
inject: {
myCompanyStore: "companyStore"
},
config: {
myCompanyStore: null
},
init: function() {
return this.callParent(arguments);
}
});
The inject
property is handled differently than most other object properties. Normally, if a superclass declares a property and a subclass declares the same property, the subclass property overrides the superclass property. In most cases, this is what you want. In the case of injections, this would be a major limitation because you'd have to duplicate any parent class injections in all of its child classes.
When a superclass and a subclass both define injections, the injection configurations are merged together. This means you can declare common injections in a superclass, and more specific injections in subclasses. In cases where both superclass and subclass specify the same dependency provider name, the configuration in the subclass takes precedence.
That's really all there is to the most common and basic way to inject dependencies into your classes. Next, we'll look at how to access views from within our ViewControllers
.