Last active
June 24, 2016 21:38
-
-
Save matjaz/62e5e6b7073ee09b56016eaadaefa3de to your computer and use it in GitHub Desktop.
aurelia-property-injection - based on https://github.com/matjaz/aurelia-property-injection & https://github.com/heruan/aurelia-property-injection
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {autoinject, inject} from './decorators' | |
class Greeter { | |
welcome(name): string { | |
return `Welcome ${name}!`; | |
} | |
} | |
@autoinject // used for constructor DI | |
export class App { | |
@autoinject greeter: Greeter; // magic | |
@inject(Greeter) // used for non-typed languages | |
greeter2: Greeter; | |
constructor (private g: Greeter) { | |
console.log(this.g) | |
console.log(this.g === this.greeter) // true | |
console.log(this.g === this.greeter2) // true | |
// return this | |
// constructor returns new object: | |
// return { | |
// greeatAll() { | |
// console.log(this.greeter.welcome('my master')) | |
// } | |
// } | |
} | |
greetAll() { | |
this.message = this.greeter.welcome('everybody'); | |
} | |
message: string = 'Welcome!'; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {metadata} from 'aurelia-metadata'; | |
import {PropertyInjectorInvoker} from './invoker'; | |
import {inject} from 'aurelia-property-injection-heruan'; // heruan implementation | |
export function autoinject (potentialTarget?: any, potentialKey?: any): any { | |
const deco = function (target, key, descriptor?) { | |
if (!key) { | |
target.inject = metadata.getOwn(metadata.paramTypes, target, key) || Object.freeze([]); | |
} else if (!descriptor) { | |
let targetConstructor = target.constructor; | |
if (!targetConstructor.injectProperties) { | |
targetConstructor.injectProperties = Object.create(null); | |
// set invoker for constructor function | |
metadata.define(metadata.invoker, PropertyInjectorInvoker.instance, targetConstructor); | |
} | |
targetConstructor.injectProperties[key] = metadata.getOwn('design:type', target, key); | |
} | |
}; | |
return potentialTarget ? deco(potentialTarget, potentialKey) : deco; | |
} | |
export {inject} from 'aurelia-property-injection-heruan'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {Invoker} from 'aurelia-dependency-injection'; | |
let singleton; | |
export class PropertyInjectorInvoker implements Invoker { | |
static get instance () { | |
return singleton || (singleton = new PropertyInjectorInvoker); | |
} | |
} | |
PropertyInjectorInvoker.prototype.invoke = invoke; | |
PropertyInjectorInvoker.prototype.invokeWithDynamicDependencies = invoke; | |
function invoke (container, fn, staticDependencies, dynamicDependencies) { | |
var injectProps; | |
const injectProperties = fn.injectProperties; | |
if (injectProperties) { | |
injectProps = Object.create(null); | |
for (let property in injectProperties) { | |
injectProps[property] = { | |
value: container.get(injectProperties[property]) | |
}; | |
} | |
} | |
// inject properties as soon as object is created, before calling constructor | |
let instance = Object.create(fn.prototype || null, injectProps); | |
let i = staticDependencies.length; | |
let args = new Array(i); | |
while (i--) { | |
args[i] = container.get(staticDependencies[i]); | |
} | |
if (dynamicDependencies) { | |
args = args.concat(dynamicDependencies); | |
} | |
var ctReturn = fn.apply(instance, args); | |
if (ctReturn && ctReturn !== instance && typeof ctReturn === 'object') { | |
// if constructor returns object inject properties to new object | |
instance = ctReturn; | |
if (injectProperties) { | |
for (let property in injectProperties) { | |
Object.defineProperty(instance, property, { | |
value: container.get(injectProperties[property]) | |
}); | |
} | |
} | |
} | |
return instance; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Not really.
Object.create
creates new object with prototype offn
and then we apply fn as constructor function. (same asnew
)In JavaScript constructor can return different object, hence the second
injectProps()
(not used/commented out in this gist). But it looks this doesn't work well with Aurelia.