5

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... :(

Community
  • 1
  • 1
Vaccano
  • 78,325
  • 149
  • 468
  • 850

1 Answers1

8

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);
Jeremy Danyow
  • 26,470
  • 12
  • 87
  • 133
  • Thank you! You are right about using breeze's change notification. (I was just so into Aurelia's system, I forgot. Thanks again! – Vaccano Mar 25 '16 at 18:46
  • Is it bad to use the `BindingEngine` instead of breeze's system? I wired up the binding engine and it worked great. I think I prefer the `BindingEngine` personally, but if there a a reason breeze's system I would like to know it. – Vaccano Mar 25 '16 at 18:56
  • If you're using aurelia-breeze, the binding system is using the breeze system, so ultimately you are indirectly using the breeze system. I would go with the native breeze system. It avoids the bad pattern of circumventing constructor injection. – Jeremy Danyow Mar 25 '16 at 18:58
  • 1
    @JeremyDanyow I tried this with `aurelia-dependency-injection@1.3.1` and it works now without `aurelia.container.makeGlobal();`. Is it intended behavior? – valichek Feb 18 '18 at 10:59