Search code examples
javascriptaureliaaurelia-di

Get access to Aurelia's Dependency Injection system without constructor injection


Is there a way to get access to Aurelia's Dependency Injection system without constructor injection.

I have a class called Box. I need to know when one of its properties change so I can update my validation. I found that I can use bindingEngine.propertyObserver from this answer.

But my instances of Box are created by BreezeJs, not Aurelia. So using @inject (or @autoinject in my case) to get the instance of bindingEngine is not going to work.

I saw aurelia.container.get will let me resolve from Aurelia's DI framework. But that needs the current instance of the Aurelia object. The only way I can see to get that is... constructor injection!

So, to get around constructor injection, you need... constructor injection!

I hope I am missing something and there is another way to get an instance of bindingEngine without constructor injection.

NOTE: For now I will just convert my variable in to a javascript property and fire an changed event on my own. But I know that this is going to move me to dirty checking... :(


Solution

  • If you want to know when a breeze entity's properties change, use the entityAspect.propertyChanged event:

    http://breeze.github.io/doc-js/api-docs/classes/EntityAspect.html#event_propertyChanged

    order.entityAspect.propertyChanged.subscribe(
    function (propertyChangedArgs) {
        // this code will be executed anytime a property value changes on the 'order' entity.
        var entity = propertyChangedArgs.entity; // Note: entity === order
        var propertyNameChanged = propertyChangedArgs.propertyName;
        var oldValue = propertyChangedArgs.oldValue;
        var newValue = propertyChangedArgs.newValue;
    });
    

    Circumventing constructor injection is not recommended. It violates the dependency inversion principle, however there is a mechanism for doing so:

    main.js

    export function configure(aurelia) {
      aurelia.container.makeGlobal();
      ...
    }
    

    box.js

    import {Container} from 'aurelia-dependency-injection';
    
    let bindingEngine = Container.instance.get(BindingEngine);