diff --git a/harmony-proxy/harmony-proxy-tests.ts b/harmony-proxy/harmony-proxy-tests.ts
new file mode 100644
index 000000000..4c011d5fd
--- /dev/null
+++ b/harmony-proxy/harmony-proxy-tests.ts
@@ -0,0 +1,27 @@
+///
+
+import * as Proxy from "harmony-proxy";
+
+interface IKatana {
+ use: () => void;
+}
+
+class Katana implements IKatana {
+ public use() {
+ console.log("Used Katana!");
+ }
+}
+
+let handler = {
+ apply: function(target: any, thisArg: any, argArray: any) {
+ console.log(`Starting: ${performance.now()}`);
+ let result = target.apply(thisArg, argArray);
+ console.log(`Finished: ${performance.now()}`);
+ return result;
+ }
+};
+
+let katana = new Katana();
+
+let katanaProxy = new Proxy(katana, handler);
+katanaProxy.use();
diff --git a/harmony-proxy/harmony-proxy.d.ts b/harmony-proxy/harmony-proxy.d.ts
new file mode 100644
index 000000000..dba832c14
--- /dev/null
+++ b/harmony-proxy/harmony-proxy.d.ts
@@ -0,0 +1,35 @@
+// Type definitions for harmony-proxy 1.0.0
+// Project: https://www.npmjs.com/package/harmony-proxy
+// Definitions by: Remo Jansen
+// Definitions: https://github.com/borisyankov/DefinitelyTyped
+
+declare module harmonyProxy {
+ type PropertyKey = string | number | symbol;
+
+ interface ProxyHandler {
+ getPrototypeOf? (target: T): any;
+ setPrototypeOf? (target: T, v: any): boolean;
+ isExtensible? (target: T): boolean;
+ preventExtensions? (target: T): boolean;
+ getOwnPropertyDescriptor? (target: T, p: PropertyKey): PropertyDescriptor;
+ has? (target: T, p: PropertyKey): boolean;
+ get? (target: T, p: PropertyKey, receiver: any): any;
+ set? (target: T, p: PropertyKey, value: any, receiver: any): boolean;
+ deleteProperty? (target: T, p: PropertyKey): boolean;
+ defineProperty? (target: T, p: PropertyKey, attributes: PropertyDescriptor): boolean;
+ enumerate? (target: T): PropertyKey[];
+ ownKeys? (target: T): PropertyKey[];
+ apply? (target: T, thisArg: any, argArray?: any): any;
+ construct? (target: T, thisArg: any, argArray?: any): any;
+ }
+
+ interface ProxyConstructor {
+ revocable(target: T, handler: ProxyHandler): { proxy: T; revoke: () => void; };
+ new (target: T, handler: ProxyHandler): T
+ }
+}
+
+declare module "harmony-proxy" {
+ let _Proxy: harmonyProxy.ProxyConstructor;
+ export = _Proxy;
+}
diff --git a/inversify/inversify-global-tests.ts b/inversify/inversify-global-tests.ts
new file mode 100644
index 000000000..ab1ac4b11
--- /dev/null
+++ b/inversify/inversify-global-tests.ts
@@ -0,0 +1,193 @@
+///
+
+module global_module_test {
+
+ interface INinja {
+ fight(): string;
+ sneak(): string;
+ }
+
+ interface IKatana {
+ hit(): string;
+ }
+
+ interface IShuriken {
+ throw(): string;
+ }
+
+ class Katana implements IKatana {
+ public hit() {
+ return "cut!";
+ }
+ }
+
+ class Shuriken implements IShuriken {
+ public throw() {
+ return "hit!";
+ }
+ }
+
+ @inversify.inject("IKatana", "IShuriken")
+ class Ninja implements INinja {
+
+ private _katana: IKatana;
+ private _shuriken: IShuriken;
+
+ public constructor(katana: IKatana, shuriken: IShuriken) {
+ this._katana = katana;
+ this._shuriken = shuriken;
+ }
+
+ public fight() { return this._katana.hit(); };
+ public sneak() { return this._shuriken.throw(); };
+
+ }
+
+ let kernel = new inversify.Kernel();
+ kernel.bind("INinja").to(Ninja);
+ kernel.bind("IKatana").to(Katana);
+ kernel.bind("IShuriken").to(Shuriken).inSingletonScope();
+
+ let ninja = kernel.get("INinja");
+ console.log(ninja);
+
+ // Unbind
+ kernel.unbind("INinja");
+ kernel.unbindAll();
+
+ // Kernel modules
+ let module: inversify.IKernelModule = (k: inversify.IKernel) => {
+ k.bind("INinja").to(Ninja);
+ k.bind("IKatana").to(Katana).inTransientScope();
+ k.bind("IShuriken").to(Shuriken).inSingletonScope();
+ };
+
+ let options: inversify.IKernelOptions = {
+ middleware: [],
+ modules: [module]
+ };
+
+ kernel = new inversify.Kernel(options);
+ let ninja2 = kernel.get("INinja");
+ console.log(ninja2);
+
+ // binding types
+ kernel.bind("IKatana").to(Katana);
+ kernel.bind("IKatana").toValue(new Katana());
+
+ kernel.bind>("IKatana").toConstructor(Katana);
+
+ kernel.bind>("IKatana").toFactory((context) => {
+ return () => {
+ return kernel.get("IKatana");
+ };
+ });
+
+ kernel.bind>("IKatana").toAutoFactory();
+
+ kernel.bind>("IKatana").toProvider((context) => {
+ return () => {
+ return new Promise((resolve) => {
+ let katana = kernel.get("IKatana");
+ resolve(katana);
+ });
+ };
+ });
+
+ kernel.bind("IKatana").to(Katana).proxy((katanaToBeInjected: IKatana) => {
+ // BLOCK http://stackoverflow.com/questions/35906938/how-to-enable-harmony-proxies-in-gulp-mocha
+ /*
+ let handler = {
+ apply: function(target, thisArgument, argumentsList) {
+ console.log(`Starting: ${performance.now()}`);
+ let result = target.apply(thisArgument, argumentsList);
+ console.log(`Finished: ${performance.now()}`);
+ return result;
+ }
+ };
+ return new Proxy(katanaToBeInjected, handler);
+ */
+ return katanaToBeInjected;
+ });
+
+ interface IWeapon {}
+ interface ISamurai {
+ katana: IWeapon;
+ shuriken: IWeapon;
+ }
+
+ @inversify.inject("IWeapon", "IWeapon")
+ class Samurai implements ISamurai {
+ public katana: IWeapon;
+ public shuriken: IWeapon;
+ public constructor(
+ @inversify.tagged("canThrow", false) katana: IWeapon,
+ @inversify.tagged("canThrow", true) shuriken: IWeapon
+ ) {
+ this.katana = katana;
+ this.shuriken = shuriken;
+ }
+ }
+
+ kernel.bind("Samurai").to(Samurai);
+ kernel.bind("IWeapon").to(Katana).whenTargetTagged("canThrow", false);
+ kernel.bind("IWeapon").to(Shuriken).whenTargetTagged("canThrow", true);
+
+ let throwable = inversify.tagged("canThrow", true);
+ let notThrowable = inversify.tagged("canThrow", false);
+
+ @inversify.inject("IWeapon", "IWeapon")
+ class Samurai2 implements ISamurai {
+ public katana: IWeapon;
+ public shuriken: IWeapon;
+ public constructor(
+ @throwable("canThrow", false) katana: IWeapon,
+ @notThrowable("canThrow", true) shuriken: IWeapon
+ ) {
+ this.katana = katana;
+ this.shuriken = shuriken;
+ }
+ }
+
+ @inversify.inject("IWeapon", "IWeapon")
+ class Samurai3 implements ISamurai {
+ public katana: IWeapon;
+ public shuriken: IWeapon;
+ public constructor(
+ @inversify.named("strong") katana: IWeapon,
+ @inversify.named("weak") shuriken: IWeapon
+ ) {
+ this.katana = katana;
+ this.shuriken = shuriken;
+ }
+ }
+
+ kernel.bind("ISamurai").to(Samurai3);
+ kernel.bind("IWeapon").to(Katana).whenTargetNamed("strong");
+ kernel.bind("IWeapon").to(Shuriken).whenTargetNamed("weak");
+
+ @inversify.inject("IWeapon", "IWeapon")
+ @inversify.paramNames("katana", "shuriken")
+ class Samurai4 implements ISamurai {
+ public katana: IWeapon;
+ public shuriken: IWeapon;
+ public constructor(
+ katana: IWeapon,
+ shuriken: IWeapon
+ ) {
+ this.katana = katana;
+ this.shuriken = shuriken;
+ }
+ }
+
+ kernel.bind("ISamurai").to(Samurai4);
+
+ kernel.bind("IWeapon").to(Katana).when((request: inversify.IRequest) => {
+ return request.target.name.equals("katana");
+ });
+
+ kernel.bind("IWeapon").to(Shuriken).when((request: inversify.IRequest) => {
+ return request.target.name.equals("shuriken");
+ });
+
+}
diff --git a/inversify/inversify-tests.ts b/inversify/inversify-tests.ts
index 46b5cab97..8d2d99d5c 100644
--- a/inversify/inversify-tests.ts
+++ b/inversify/inversify-tests.ts
@@ -1,75 +1,200 @@
///
-interface FooInterface {
- name : string;
- greet() : string;
+import {
+ Kernel,
+ inject, tagged, named, paramNames,
+ IKernel, IKernelOptions, INewable,
+ IKernelModule, IFactory, IProvider, IRequest
+} from "inversify";
+
+module external_module_test {
+
+ interface INinja {
+ fight(): string;
+ sneak(): string;
+ }
+
+ interface IKatana {
+ hit(): string;
+ }
+
+ interface IShuriken {
+ throw(): string;
+ }
+
+ class Katana implements IKatana {
+ public hit() {
+ return "cut!";
+ }
+ }
+
+ class Shuriken implements IShuriken {
+ public throw() {
+ return "hit!";
+ }
+ }
+
+ @inject("IKatana", "IShuriken")
+ class Ninja implements INinja {
+
+ private _katana: IKatana;
+ private _shuriken: IShuriken;
+
+ public constructor(katana: IKatana, shuriken: IShuriken) {
+ this._katana = katana;
+ this._shuriken = shuriken;
+ }
+
+ public fight() { return this._katana.hit(); };
+ public sneak() { return this._shuriken.throw(); };
+
+ }
+
+ let kernel = new Kernel();
+ kernel.bind("INinja").to(Ninja);
+ kernel.bind("IKatana").to(Katana);
+ kernel.bind("IShuriken").to(Shuriken).inSingletonScope();
+
+ let ninja = kernel.get("INinja");
+ console.log(ninja);
+
+ // Unbind
+ kernel.unbind("INinja");
+ kernel.unbindAll();
+
+ // Kernel modules
+ let module: IKernelModule = (k: IKernel) => {
+ k.bind("INinja").to(Ninja);
+ k.bind("IKatana").to(Katana).inTransientScope();
+ k.bind("IShuriken").to(Shuriken).inSingletonScope();
+ };
+
+ let options: IKernelOptions = {
+ middleware: [],
+ modules: [module]
+ };
+
+ kernel = new Kernel(options);
+ let ninja2 = kernel.get("INinja");
+ console.log(ninja2);
+
+ // binding types
+ kernel.bind("IKatana").to(Katana);
+ kernel.bind("IKatana").toValue(new Katana());
+
+ kernel.bind>("IKatana").toConstructor(Katana);
+
+ kernel.bind>("IKatana").toFactory((context) => {
+ return () => {
+ return kernel.get("IKatana");
+ };
+ });
+
+ kernel.bind>("IKatana").toAutoFactory();
+
+ kernel.bind>("IKatana").toProvider((context) => {
+ return () => {
+ return new Promise((resolve) => {
+ let katana = kernel.get("IKatana");
+ resolve(katana);
+ });
+ };
+ });
+
+ kernel.bind("IKatana").to(Katana).proxy((katanaToBeInjected: IKatana) => {
+ // BLOCK http://stackoverflow.com/questions/35906938/how-to-enable-harmony-proxies-in-gulp-mocha
+ /*
+ let handler = {
+ apply: function(target, thisArgument, argumentsList) {
+ console.log(`Starting: ${performance.now()}`);
+ let result = target.apply(thisArgument, argumentsList);
+ console.log(`Finished: ${performance.now()}`);
+ return result;
+ }
+ };
+ return new Proxy(katanaToBeInjected, handler);
+ */
+ return katanaToBeInjected;
+ });
+
+ interface IWeapon {}
+ interface ISamurai {
+ katana: IWeapon;
+ shuriken: IWeapon;
+ }
+
+ @inject("IWeapon", "IWeapon")
+ class Samurai implements ISamurai {
+ public katana: IWeapon;
+ public shuriken: IWeapon;
+ public constructor(
+ @tagged("canThrow", false) katana: IWeapon,
+ @tagged("canThrow", true) shuriken: IWeapon
+ ) {
+ this.katana = katana;
+ this.shuriken = shuriken;
+ }
+ }
+
+ kernel.bind("Samurai").to(Samurai);
+ kernel.bind("IWeapon").to(Katana).whenTargetTagged("canThrow", false);
+ kernel.bind("IWeapon").to(Shuriken).whenTargetTagged("canThrow", true);
+
+ let throwable = tagged("canThrow", true);
+ let notThrowable = tagged("canThrow", false);
+
+ @inject("IWeapon", "IWeapon")
+ class Samurai2 implements ISamurai {
+ public katana: IWeapon;
+ public shuriken: IWeapon;
+ public constructor(
+ @throwable("canThrow", false) katana: IWeapon,
+ @notThrowable("canThrow", true) shuriken: IWeapon
+ ) {
+ this.katana = katana;
+ this.shuriken = shuriken;
+ }
+ }
+
+ @inject("IWeapon", "IWeapon")
+ class Samurai3 implements ISamurai {
+ public katana: IWeapon;
+ public shuriken: IWeapon;
+ public constructor(
+ @named("strong") katana: IWeapon,
+ @named("weak") shuriken: IWeapon
+ ) {
+ this.katana = katana;
+ this.shuriken = shuriken;
+ }
+ }
+
+ kernel.bind("ISamurai").to(Samurai3);
+ kernel.bind("IWeapon").to(Katana).whenTargetNamed("strong");
+ kernel.bind("IWeapon").to(Shuriken).whenTargetNamed("weak");
+
+ @inject("IWeapon", "IWeapon")
+ @paramNames("katana", "shuriken")
+ class Samurai4 implements ISamurai {
+ public katana: IWeapon;
+ public shuriken: IWeapon;
+ public constructor(
+ katana: IWeapon,
+ shuriken: IWeapon
+ ) {
+ this.katana = katana;
+ this.shuriken = shuriken;
+ }
+ }
+
+ kernel.bind("ISamurai").to(Samurai4);
+
+ kernel.bind("IWeapon").to(Katana).when((request: IRequest) => {
+ return request.target.name.equals("katana");
+ });
+
+ kernel.bind("IWeapon").to(Shuriken).when((request: IRequest) => {
+ return request.target.name.equals("shuriken");
+ });
+
}
-
-interface BarInterface {
- name : string;
- greet() : string;
-}
-
-interface FooBarInterface {
- foo : FooInterface;
- bar : BarInterface;
- greet() : string;
-}
-
-class Foo implements FooInterface {
- public name : string;
- constructor() {
- this.name = "foo";
- }
- public greet() : string {
- return this.name;
- }
-}
-
-class Bar implements BarInterface {
- public name : string;
- constructor() {
- this.name = "bar";
- }
- public greet() : string {
- return this.name;
- }
-}
-
-class FooBar implements FooBarInterface {
- public foo : FooInterface;
- public bar : BarInterface;
- constructor(FooInterface : FooInterface, BarInterface : BarInterface) {
- this.foo = FooInterface;
- this.bar = BarInterface;
- }
- public greet() : string{
- return this.foo.greet() + this.bar.greet();
- }
-}
-
-// Kernel
-var kernel = new inversify.Kernel();
-
-// Identifiers
-var fooRuntimeIdentifier = "FooInterface";
-var barRuntimeIdentifier = "BarInterface";
-var fooBarRuntimeIdentifier = "FooBarInterface";
-
-// Bindings
-var fooBinding = new inversify.TypeBinding(fooRuntimeIdentifier, Foo);
-var barBinding = new inversify.TypeBinding(barRuntimeIdentifier, Bar);
-var fooBarBinding = new inversify.TypeBinding(fooBarRuntimeIdentifier, FooBar);
-
-kernel.bind(fooBinding);
-kernel.bind(barBinding);
-kernel.bind(fooBarBinding);
-
-// Resolve
-var foo = kernel.resolve(fooRuntimeIdentifier);
-var bar = kernel.resolve(barRuntimeIdentifier);
-var fooBar = kernel.resolve(fooBarRuntimeIdentifier);
-
-// Unbind
-kernel.unbind(fooRuntimeIdentifier);
-kernel.unbindAll();
diff --git a/inversify/inversify.d.ts b/inversify/inversify.d.ts
index f3c924e82..fe2e3c1f7 100644
--- a/inversify/inversify.d.ts
+++ b/inversify/inversify.d.ts
@@ -1,51 +1,143 @@
-// Type definitions for inversify 1.0.0
+// Type definitions for inversify 2.0.0-alpha.3
// Project: https://github.com/inversify/InversifyJS
// Definitions by: inversify
// Definitions: https://github.com/borisyankov/DefinitelyTyped
-declare module inversify {
-
- interface TypeBindingInterface {
- runtimeIdentifier : string;
- implementationType : { new(): TServiceType ;};
- cache : TServiceType;
- scope : number; // TypeBindingScopeEnum
- }
+///
- interface KernelInterface {
- bind(typeBinding : TypeBindingInterface) : void;
- unbind(runtimeIdentifier : string) : void;
- unbindAll() : void;
- resolve(runtimeIdentifier : string) : TImplementationType;
- }
+declare namespace inversify {
- enum TypeBindingScopeEnum {
- Transient = 0,
- Singleton = 1,
- }
+ interface IKernelConstructor {
+ new(options?: IKernelOptions): IKernel;
+ }
- class TypeBinding implements TypeBindingInterface {
- runtimeIdentifier: string;
- implementationType: {
- new (): TServiceType;
- };
- cache: TServiceType;
- scope: TypeBindingScopeEnum;
- constructor(runtimeIdentifier: string, implementationType: {
- new (...args: any[]): TServiceType;
- }, scopeType?: TypeBindingScopeEnum);
- }
+ export interface IKernel {
+ bind(runtimeIdentifier: string): IBindingToSyntax;
+ unbind(runtimeIdentifier: string): void;
+ unbindAll(): void;
+ get(runtimeIdentifier: string): T;
+ getAll(runtimeIdentifier: string): T[];
+ }
- class Kernel implements KernelInterface {
- private _bindings;
- bind(typeBinding: TypeBindingInterface): void;
- unbind(runtimeIdentifier: string): void;
- unbindAll(): void;
- resolve(runtimeIdentifier: string): TImplementationType;
- private _validateBinding(typeBinding);
- private _getConstructorArguments(func);
- private _injectDependencies(func);
- private _construct(constr, args);
- constructor();
- }
+ export interface IKernelOptions {
+ middleware?: IMiddleware[];
+ modules?: IKernelModule[];
+ }
+
+ interface IMiddleware extends Function {
+ (...args: any[]): any;
+ }
+
+ export interface IKernelModule extends Function {
+ (kernel: IKernel): void;
+ }
+
+ interface IBindingToSyntax {
+ to(constructor: { new(...args: any[]): T; }): IBindingInWhenProxySyntax;
+ toValue(value: T): IBindingInWhenProxySyntax;
+ toConstructor(constructor: INewable): IBindingInWhenProxySyntax;
+ toFactory(factory: IFactoryCreator): IBindingInWhenProxySyntax;
+ toAutoFactory(): IBindingInWhenProxySyntax;
+ toProvider(provider: IProviderCreator): IBindingInWhenProxySyntax;
+ }
+
+ interface IBindingInWhenProxySyntax {
+ inTransientScope(): IBindingInWhenProxySyntax;
+ inSingletonScope(): IBindingInWhenProxySyntax;
+ when(constraint: (request: IRequest) => boolean): IBindingInWhenProxySyntax;
+ whenTargetNamed(name: string): IBindingInWhenProxySyntax;
+ whenTargetTagged(tag: string, value: any): IBindingInWhenProxySyntax;
+ proxy(fn: (injectable: T) => T): IBindingInWhenProxySyntax;
+ }
+
+ export interface IFactory extends Function {
+ (): T;
+ }
+
+ interface IFactoryCreator extends Function {
+ (context: IContext): IFactory;
+ }
+
+ export interface INewable {
+ new(...args: any[]): T;
+ }
+
+ export interface IProvider extends Function {
+ (): Promise;
+ }
+
+ interface IProviderCreator extends Function {
+ (context: IContext): IProvider;
+ }
+
+ export interface IContext {
+ kernel: IKernel;
+ plan: IPlan;
+ addPlan(plan: IPlan): void;
+ }
+
+ export interface IPlan {
+ parentContext: IContext;
+ rootRequest: IRequest;
+ }
+
+ export interface IRequest {
+ service: string;
+ parentContext: IContext;
+ parentRequest: IRequest;
+ childRequests: IRequest[];
+ target: ITarget;
+ bindings: IBinding[];
+ addChildRequest(
+ service: string,
+ bindings: (IBinding|IBinding[]),
+ target: ITarget): IRequest;
+ }
+
+ export interface IBinding {
+ runtimeIdentifier: string;
+ implementationType: INewable;
+ factory: IFactoryCreator;
+ provider: IProviderCreator;
+ constraint: (request: IRequest) => boolean;
+ proxyMaker: (injectable: T) => T;
+ cache: T;
+ scope: number; // BindingScope
+ type: number; // BindingType
+ }
+
+ export interface ITarget {
+ service: IQueryableString;
+ name: IQueryableString;
+ metadata: Array;
+ isArray(): boolean;
+ isNamed(): boolean;
+ isTagged(): boolean;
+ matchesName(name: string): boolean;
+ matchesTag(name: IMetadata): boolean;
+ }
+
+ export interface IQueryableString {
+ startsWith(searchString: string): boolean;
+ endsWith(searchString: string): boolean;
+ contains(searchString: string): boolean;
+ equals(compareString: string): boolean;
+ value(): string;
+ }
+
+ export interface IMetadata {
+ key: string;
+ value: any;
+ }
+
+ export var Kernel: IKernelConstructor;
+ export var decorate: any;
+ export function inject(...typeIdentifiers: string[]): (typeConstructor: any) => void;
+ export var tagged: any;
+ export var named: any;
+ export var paramNames: any;
+}
+
+declare module "inversify" {
+ export = inversify;
}