From 6591aeb9a8f6b8b1e831fe337d4f11b5a165a298 Mon Sep 17 00:00:00 2001 From: dcrusader Date: Mon, 5 Jan 2015 09:52:48 -0800 Subject: [PATCH 1/8] TypeScript definitions for di-lite 0.3.3 TypeScript definitions for di-lite 0.3.3 (https://github.com/NickQiZhu/di.js) --- di-lite/di-lite.d.ts | 58 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 di-lite/di-lite.d.ts diff --git a/di-lite/di-lite.d.ts b/di-lite/di-lite.d.ts new file mode 100644 index 000000000..fe279b60a --- /dev/null +++ b/di-lite/di-lite.d.ts @@ -0,0 +1,58 @@ +// Type definitions for di-lite 0.3.3 +// Project: https://github.com/NickQiZhu/di.js +// Definitions by: Timothy Morris +// Definitions: https://github.com/borisyankov/DefinitelyTyped + +interface di { + version: string; + createContext(): CreateContext; + dependencyExpression(depExp: string): string; + entry(name: string, ctx: CreateContext); + strategy: Strategy; + factory: Factory; + utils: Utils; +} + +interface CreateContext { + map: Object; + entry(name: string): Object; + register(name: string, service: any): CreateContext; + has(name: string): boolean; + "get"(name: string): any; + create(name: string, args: any) + initialize(): void; + clear(): void; + inject(name: string, o: Object, dependencies: string): Object; + ready(o: Function): Object; + ready(o: Object): Object; +} + +interface Entry { + create(newArgs: any): Entry; + object(): Object; + object(o: Object): Entry; + strategy(s: Function): Entry; + type(t: any): Entry; + dependencies(d: string): Entry; + args(a: any): Entry; + factory(f: Function): Entry; +} + +interface Strategy { + proto(name: string, object: Object, type: any, args: any, ctx: CreateContext, dependencies: string): Object; + singleton(name: string, object: Object, type: any, args: any, ctx?: CreateContext, dependencies?: string): Object; +} + +interface Factory { + "constructor"(type: any, args: any): Object; + func(type: any, args: any): any; +} + +interface Utils { + invokeStmt(args: any, op: string): string; +} + +declare var di: di; +declare module "di" { + export = di; +} From 302b3afa2ec9ebeae59bde791677e89fad6dbc3a Mon Sep 17 00:00:00 2001 From: dcrusader Date: Mon, 5 Jan 2015 11:35:11 -0800 Subject: [PATCH 2/8] Prefix interfaces with Di Prefixed interfaces with Di to help organize intellisense --- di-lite/di-lite.d.ts | 46 ++++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/di-lite/di-lite.d.ts b/di-lite/di-lite.d.ts index fe279b60a..062434dea 100644 --- a/di-lite/di-lite.d.ts +++ b/di-lite/di-lite.d.ts @@ -3,20 +3,20 @@ // Definitions by: Timothy Morris // Definitions: https://github.com/borisyankov/DefinitelyTyped -interface di { +interface DiLite { version: string; - createContext(): CreateContext; + createContext(): DiCreateContext; dependencyExpression(depExp: string): string; - entry(name: string, ctx: CreateContext); - strategy: Strategy; - factory: Factory; - utils: Utils; + entry(name: string, ctx: DiCreateContext); + strategy: DiStrategy; + factory: DiFactory; + utils: DiUtils; } -interface CreateContext { +interface DiCreateContext { map: Object; entry(name: string): Object; - register(name: string, service: any): CreateContext; + register(name: string, service: any): DiEntry; has(name: string): boolean; "get"(name: string): any; create(name: string, args: any) @@ -27,32 +27,32 @@ interface CreateContext { ready(o: Object): Object; } -interface Entry { - create(newArgs: any): Entry; +interface DiEntry { + create(newArgs: any): DiEntry; object(): Object; - object(o: Object): Entry; - strategy(s: Function): Entry; - type(t: any): Entry; - dependencies(d: string): Entry; - args(a: any): Entry; - factory(f: Function): Entry; + object(o: Object): DiEntry; + strategy(s: Function): DiEntry; + type(t: any): DiEntry; + dependencies(d: string): DiEntry; + args(a: any): DiEntry; + factory(f: Function): DiEntry; } -interface Strategy { - proto(name: string, object: Object, type: any, args: any, ctx: CreateContext, dependencies: string): Object; - singleton(name: string, object: Object, type: any, args: any, ctx?: CreateContext, dependencies?: string): Object; +interface DiStrategy { + proto(name: string, object: Object, type: any, args: any, ctx: DiCreateContext, dependencies: string): Object; + singleton(name: string, object: Object, type: any, args: any, ctx?: DiCreateContext, dependencies?: string): Object; } -interface Factory { +interface DiFactory { "constructor"(type: any, args: any): Object; func(type: any, args: any): any; } -interface Utils { +interface DiUtils { invokeStmt(args: any, op: string): string; } -declare var di: di; -declare module "di" { +declare module "di-lite" { export = di; } +declare var di: DiLite; From 7eabe68bb77b81cbe4e9ca07da8da90c515ad72a Mon Sep 17 00:00:00 2001 From: dcrusader Date: Mon, 5 Jan 2015 18:55:48 -0800 Subject: [PATCH 3/8] Add di-lite tests --- di-lite/di-lite-test.ts | 137 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 di-lite/di-lite-test.ts diff --git a/di-lite/di-lite-test.ts b/di-lite/di-lite-test.ts new file mode 100644 index 000000000..fbff668f1 --- /dev/null +++ b/di-lite/di-lite-test.ts @@ -0,0 +1,137 @@ +interface Dependency { + dependencies?: string; +} + +function doTest(test: (ctx: DiCreateContext, ...obj: Dependency[]) => void) { + // create di context + var ctx = di.createContext(), + A: Dependency = () => { + this.dependencies = "b, c"; + }, + B: Dependency = () => { + this.dependencies = "c"; + }, + C: Dependency = () => {}; + + // register a class with an unique name + ctx.register("a", A); + ctx.register("b", B); + ctx.register("c", C); + + test(ctx, A, B, C); +} + +module BasicWiring { + doTest(ctx => { + // initialize di container so all singleton(default) objects will be wired at this stage + ctx.initialize(); + + var instanceOfA = ctx.get("a"); + instanceOfA.b === ctx.get("b"); // true + instanceOfA.c === ctx.get("c"); // true + + var instanceOfB = ctx.get("b"); + instanceOfB.c === ctx.get("c"); // true + }); +} + +module WiringWithAssignment { + doTest((ctx, A) => { + A.dependencies = "bee=b, c"; // mix explicit and implicit assignment + + ctx.initialize(); + + var instanceOfA = ctx.get("a"); + instanceOfA.bee === ctx.get("b"); // true - explicit assignment + instanceOfA.c === ctx.get("c"); // true - implicit assignment + }); +} + +module PassiveDependencyResolution { + doTest((ctx, A) => { + ctx.register("a", A); + ctx.get("a"); // this triggers the dependency resolution for "a" alone + ctx.initialize(); + }); +} + +module PrototypeStrategy { + doTest((ctx, A) => { + ctx.register("prototype", A).strategy(di.strategy.proto); + ctx.get("prototype") === ctx.get("prototype"); // false + ctx.create("prototype", 100); // create can be used if you want to explicitly pass in a new parameter + }); +} + +module PassingConstructorArguments { + class ProfileView { } + + doTest(ctx => { + ctx.register("str", String, "hello world"); // signle simple argument + ctx.register("profileView", ProfileView, { el: "#profile_div" }); // signle object literal argument + ctx.register("array", Array, ["Saab", "Volvo", "BMW"]); // multiple argument is passed in using an array + }); +} + +module CyclicalDependency { + doTest((ctx, A, B) => { + A.dependencies = "b"; + B.dependencies = "a"; + + ctx.register("a", A); + ctx.register("b", B); + + ctx.initialize(); + + ctx.get("a").b === ctx.get("b"); // true + ctx.get("b").a === ctx.get("a"); // true + ctx.get("a").b.a === ctx.get("a"); // true + ctx.get("b").a.b === ctx.get("b"); // true + }); +} + +module FunctionalObject { + doTest(ctx => { + var FuncObject = spec => { + var that = {}; + return that; + }, + spec = []; + + ctx.register("funcObjSingleton", FuncObject, spec).factory(di.factory.func); + + // function chaining can be used to customize your object registration + ctx.register("funcObjProto", FuncObject, spec) + .strategy(di.strategy.proto) + .factory(di.factory.func); + + ctx.initialize(); + + ctx.get("funcObjSingleton"); // will return you a signleton instance of FuncObject + ctx.get("funcObjProto"); // will return you a new instance of FuncObject each time + }); +} + +module RuntimeDependenciesOverride { + doTest((ctx, A) => { + ctx.register("a", A) + .dependencies("bee=b"); // dependencies specified here will take precedence + ctx.get("a").bee === ctx.get("b"); // true + }); +} + +module CreateYourOwn { + class Backbone { + history: History = new History(); + } + + class History { + start() {} + } + + doTest(ctx => { + ctx.register("history").object(new Backbone().history); + ctx.get("history").start(); // you can use it since it is already created and initialized + ctx.initialize(); // initialize the rest of the objects + }); +} From b33ff5f0e08b2d7e22568c1f7a1c7f2caae66bdd Mon Sep 17 00:00:00 2001 From: dcrusader Date: Mon, 5 Jan 2015 18:56:12 -0800 Subject: [PATCH 4/8] Fix error revealed by tests --- di-lite/di-lite.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/di-lite/di-lite.d.ts b/di-lite/di-lite.d.ts index 062434dea..d679b00de 100644 --- a/di-lite/di-lite.d.ts +++ b/di-lite/di-lite.d.ts @@ -16,7 +16,7 @@ interface DiLite { interface DiCreateContext { map: Object; entry(name: string): Object; - register(name: string, service: any): DiEntry; + register(name: string, type?: any, args?: any): DiEntry; has(name: string): boolean; "get"(name: string): any; create(name: string, args: any) From ba80717c78458816b55b7e4d2084c9ab5807ee16 Mon Sep 17 00:00:00 2001 From: dcrusader Date: Mon, 5 Jan 2015 19:06:14 -0800 Subject: [PATCH 5/8] Add reference path to test file --- di-lite/di-lite-test.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/di-lite/di-lite-test.ts b/di-lite/di-lite-test.ts index fbff668f1..eed9c2625 100644 --- a/di-lite/di-lite-test.ts +++ b/di-lite/di-lite-test.ts @@ -1,8 +1,10 @@ +/// + interface Dependency { dependencies?: string; } -function doTest(test: (ctx: DiCreateContext, ...obj: Dependency[]) => void) { +function doTest(test: (ctx, ...obj: Dependency[]) => void) { // create di context var ctx = di.createContext(), A: Dependency = () => { @@ -92,11 +94,11 @@ module CyclicalDependency { module FunctionalObject { doTest(ctx => { - var FuncObject = spec => { + var FuncObject = (spec: any) => { var that = {}; return that; }, - spec = []; + spec: any = []; ctx.register("funcObjSingleton", FuncObject, spec).factory(di.factory.func); From 811ddbf03d9ce3aaaa9c19207c4f19bef35e5493 Mon Sep 17 00:00:00 2001 From: dcrusader Date: Mon, 5 Jan 2015 19:06:37 -0800 Subject: [PATCH 6/8] Fix build errors --- di-lite/di-lite.d.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/di-lite/di-lite.d.ts b/di-lite/di-lite.d.ts index d679b00de..946fe9a3f 100644 --- a/di-lite/di-lite.d.ts +++ b/di-lite/di-lite.d.ts @@ -7,7 +7,7 @@ interface DiLite { version: string; createContext(): DiCreateContext; dependencyExpression(depExp: string): string; - entry(name: string, ctx: DiCreateContext); + entry(name: string, ctx: DiCreateContext): DiEntry; strategy: DiStrategy; factory: DiFactory; utils: DiUtils; @@ -19,7 +19,7 @@ interface DiCreateContext { register(name: string, type?: any, args?: any): DiEntry; has(name: string): boolean; "get"(name: string): any; - create(name: string, args: any) + create(name: string, args: any): any; initialize(): void; clear(): void; inject(name: string, o: Object, dependencies: string): Object; From 3769701771f3273a903bbcd70bb2f7827137e118 Mon Sep 17 00:00:00 2001 From: dcrusader Date: Mon, 5 Jan 2015 19:09:08 -0800 Subject: [PATCH 7/8] Fix build errors harder --- di-lite/di-lite-test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/di-lite/di-lite-test.ts b/di-lite/di-lite-test.ts index eed9c2625..8d6bfb777 100644 --- a/di-lite/di-lite-test.ts +++ b/di-lite/di-lite-test.ts @@ -4,7 +4,7 @@ interface Dependency { dependencies?: string; } -function doTest(test: (ctx, ...obj: Dependency[]) => void) { +function doTest(test: (ctx: any, ...obj: Dependency[]) => void) { // create di context var ctx = di.createContext(), A: Dependency = () => { From b32b06043b299381d2333f591af792b5ce20ea43 Mon Sep 17 00:00:00 2001 From: dcrusader Date: Thu, 8 Jan 2015 10:40:09 -0800 Subject: [PATCH 8/8] Use ghost module pattern from best practices --- di-lite/di-lite.d.ts | 97 ++++++++++++++++++++++++-------------------- 1 file changed, 54 insertions(+), 43 deletions(-) diff --git a/di-lite/di-lite.d.ts b/di-lite/di-lite.d.ts index 946fe9a3f..356f70c7b 100644 --- a/di-lite/di-lite.d.ts +++ b/di-lite/di-lite.d.ts @@ -3,56 +3,67 @@ // Definitions by: Timothy Morris // Definitions: https://github.com/borisyankov/DefinitelyTyped -interface DiLite { - version: string; - createContext(): DiCreateContext; - dependencyExpression(depExp: string): string; - entry(name: string, ctx: DiCreateContext): DiEntry; - strategy: DiStrategy; - factory: DiFactory; - utils: DiUtils; -} +declare module DiLite { + interface DiLiteStatic { + version: string; + createContext(): CreateContext; + dependencyExpression(depExp: string): string; + entry(name: string, ctx: CreateContext): any; + strategy: StrategyEnum; + factory: FactoryEnum; + utils: Utils; + } -interface DiCreateContext { - map: Object; - entry(name: string): Object; - register(name: string, type?: any, args?: any): DiEntry; - has(name: string): boolean; - "get"(name: string): any; - create(name: string, args: any): any; - initialize(): void; - clear(): void; - inject(name: string, o: Object, dependencies: string): Object; - ready(o: Function): Object; - ready(o: Object): Object; -} + interface Dictionary { + [index: string]: T; + } -interface DiEntry { - create(newArgs: any): DiEntry; - object(): Object; - object(o: Object): DiEntry; - strategy(s: Function): DiEntry; - type(t: any): DiEntry; - dependencies(d: string): DiEntry; - args(a: any): DiEntry; - factory(f: Function): DiEntry; -} + interface CreateContext { + map: Dictionary; + entry(name: string): T; + register(name: string, service: T): Entry; + has(name: string): boolean; + get(name: string): any; + create(name: string, args: any): T; + initialize(): void; + clear(): void; + inject(name: string, o: T, dependencies: string): T; + ready(o: Function): T; + ready(o: any): T; + } -interface DiStrategy { - proto(name: string, object: Object, type: any, args: any, ctx: DiCreateContext, dependencies: string): Object; - singleton(name: string, object: Object, type: any, args: any, ctx?: DiCreateContext, dependencies?: string): Object; -} + interface Entry { + create(newArgs: any): Entry; + object(o: T): Entry; + object(): T; + strategy(s: Function): Entry; + strategy(): T; + type(t: T): Entry; + type(): T; + dependencies(d: T): Entry; + dependencies(): T; + args(a: T): Entry; + args(): T; + factory(f: Function): Entry; + factory(): T; + } -interface DiFactory { - "constructor"(type: any, args: any): Object; - func(type: any, args: any): any; -} + interface StrategyEnum { + proto(name: string, object: TObject, type: TType, args: any, ctx: CreateContext, dependencies: any): TObject; + singleton(name: string, object: TObject, type: TType, args: any, ctx?: CreateContext, dependencies?: any): TObject; + } -interface DiUtils { - invokeStmt(args: any, op: string): string; + interface FactoryEnum { + constructor(type: T, args: any): T; + func(type: T, args: any): T; + } + + interface Utils { + invokeStmt(args: any, op: string): string; + } } declare module "di-lite" { export = di; } -declare var di: DiLite; +declare var di: DiLite.DiLiteStatic;