using dependency injection on #titanium #alloy #TiDev

Oscar Brito

I've seen a few articles saying that using Ti.App.fireEvent everywhere is not a good practice. The solution is to use the $.trigger widget method instead. That's OK. Global events are evil!

I think that the real question is not if global events are good or evil. For me the real question is:

How can I create a maintainable Titanium app?

Alloy Controllers

When you create an Alloy widget (js + tss + xml) the compilation process will create the something like:



function Controller() {
    require("alloy/controllers/BaseController").apply(this, Array.prototype.slice.call(arguments));
    this.__controllerPath = "index";
    arguments[0] ? arguments[0]["__parentSymbol"] : null;
    arguments[0] ? arguments[0]["$model"] : null;
    arguments[0] ? arguments[0]["__itemTemplate"] : null;
    var $ = this;
    var exports = {};
    $.__views.index = Ti.UI.createWindow({
        backgroundColor: "white",
        id: "index"
    });
    $.__views.index && $.addTopLevelView($.__views.index);
    $.__views.label = Ti.UI.createLabel({
        width: Ti.UI.SIZE,
        height: Ti.UI.SIZE,
        color: "#000",
        text: "Hello, World",
        id: "label"
    });
    $.__views.index.add($.__views.label);
    exports.destroy = function() {};
    _.extend($, $.__views);



    ////// HERE goes your controller code



    _.extend($, exports);
}

var Alloy = require("alloy"), Backbone = Alloy.Backbone, _ = Alloy._;

module.exports = Controller;


The generated code has the following problems:

  1. The widget.js is not a CommonJS module, is just a bunch of code that is appended to the compiled code.

  2. There's no notion of Controller instance ( your code will be appended to the Controller function ).

  3. Because of 2) we cannot easily test our Widget because it depends of the generated structure.

  4. Because of 2) we cannot manage the Controller instances and it's dependencies without global variables ( if people tell bad things about global events, then global variables are also evil. )

  5. ... let me know of other problems!

Dependency injection on Alloy

Dependency injection is a very familiar concept that is used to reduce the complexity on large applications. Some of the advantages are:

  • Instance lifetime/registration as declarative programming

  • Instance creation using factory pattern ( provided by IOC container )

  • Instance dependencies ( declarative programming )

To make my point I've created a prototype that uses dependency injection. This creates a separation between your Business Layer and the UI.

https://github.com/aetheon/ti-app-dependency-injection-example

I would really like to know what you think. If I could get some feedback from the titanium team that would be magic.

Please share this with your Titanium devs peers.

Oscar out!