μλ
νμΈμ μ¬λ¬λΆ μ λ InversifyJS λΌλ TypeScript μ±μ© IoC 컨ν
μ΄λλ₯Ό κ°λ° service type
(μΈν°νμ΄μ€)μ implementation type
(ν΄λμ€) κ°μ λ°μΈλ©μ μ μνλ λ° μ¬μ©λλ TypeBinding<TServiceType>
λΌλ ν΄λμ€λ₯Ό ꡬννμ΅λλ€. ν΄λμ€ μ½λλ λ€μκ³Ό κ°μ΅λλ€.
// Defines allowed scope modes
enum TypeBindingScopeEnum {
Transient,
Singleton
}
class TypeBinding<TServiceType> {
// The runtime identifier used because at runtime
// we don't have interfaces
public runtimeIdentifier : string;
// The constructor of a class that must implement TServiceType
public implementationType : { new(): TServiceType ;};
// Cache used to allow singleton scope
public cache : TServiceType;
// The scope mode to be used
public scope : TypeBindingScopeEnum;
constructor(
runtimeIdentifier : string,
implementationType : { new(): TServiceType ;},
scopeType? : TypeBindingScopeEnum) {
this.runtimeIdentifier = runtimeIdentifier;
this.implementationType = implementationType;
this.cache = null;
if(typeof scopeType === "undefined") {
// Default scope is Transient
this.scope = TypeBindingScopeEnum.Transient;
}
else {
if(TypeBindingScopeEnum[scopeType]) {
this.scope = scopeType;
}
else {
var msg = `Invalid scope type ${scopeType}`;
throw new Error(msg);
}
}
}
}
TypeBinding<TServiceType>
ν΄λμ€λ₯Ό ν
μ€νΈνκΈ° μν΄ λͺ κ°μ§ μν°ν°λ₯Ό μ μνμ΅λλ€.
interface FooInterface {
logFoo() : void;
}
interface BarInterface {
logBar() : void;
}
interface FooBarInterface {
logFooBar() : void;
}
// Notice default constructor
class Foo implements FooInterface {
public logFoo(){
console.log("foo");
}
}
// Notice default constructor
class Bar implements BarInterface {
public logBar(){
console.log("bar");
}
}
// Notice dependencies on FooInterface and BarInterface on constructor
class FooBar implements FooBarInterface {
public foo : FooInterface;
public bar : BarInterface;
public logFooBar(){
console.log("foobar");
}
constructor(FooInterface : FooInterface, BarInterface : BarInterface) {
this.foo = FooInterface;
this.bar = BarInterface;
}
}
Foo
λ° Bar
ν΄λμ€μ λ¬Έμ μμ΄ TypeBinding<TServiceType>
ν΄λμ€λ₯Ό μ¬μ©ν μ μμ΅λλ€.
var fooBinding = new TypeBinding<FooInterface>("FooInterface", Foo);
var barBinding = new TypeBinding<BarInterface>("BarInterface", Bar);
λ΄ λ¬Έμ λ { new(): TServiceType ;}
λ₯Ό μ¬μ©νλ €κ³ νκ³ TServiceType
λ₯Ό ꡬννλ ν΄λμ€μ μμ±μκ° λ§€κ°λ³μκ° μλ κ²½μ° λ°μν©λλ€.
'typeof FooBar' μ νμ μΈμλ 'new () => FooBarInterface' μ νμ 맀κ°λ³μμ ν λΉν μ μμ΅λλ€.
var fooBarBinding = new TypeBinding<FooBarInterface>("FooBarInterface", FooBar);
μ΄ λ¬Έμ λ₯Ό μ΄λ»κ² ν΄κ²°ν μ μμ΅λκΉ?
κ°μ¬ ν΄μ :)
class μμ±μ λ³κ²½νμ¬ λ¬Έμ λ₯Ό ν΄κ²°νλ€κ³ μκ°ν©λλ€.
implementationType : { new(): TServiceType ;},
μκ²:
implementationType : { new(...args : any[]): TServiceType ;},
μΌλΆ λ¨μ ν μ€νΈ con νμΈμ μμ±ν©λλ€.
κ°μ¬ ν΄μ...
μ리ν! μ΄λ° μ 보 κ°μ¬ν©λλ€ :)
λλΆμ ν¨μ 맀κ°λ³μμ μ λ¬λ μμ±μμ λν΄ μ ν κ²μ¬λ₯Ό μννλ λ°©λ²μ μ°Ύκ³ μμμ΅λλ€. { new(...args : any[]): T ;}
νμ©νμ΅λλ€.
μ¦, λ°μ½λ μ΄ν° λμμμ μ ν κ²μ¬λ₯Ό μνν μ μμ΅λλ€.
function decor(oPar: {}): <TFunc extends { new (...args: any[]): A }>(target: TFunc) => void {
return function <TFunc extends { new (...args: any[]): A }>(target: TFunc): void {
console.log(oPar, target);
}
}
class A { id: string; }
// will error
@decor({})
class B { }
// Works
@decor({})
class C extends A { }
κ°μ₯ μ μ©ν λκΈ
class μμ±μ λ³κ²½νμ¬ λ¬Έμ λ₯Ό ν΄κ²°νλ€κ³ μκ°ν©λλ€.
μκ²:
μΌλΆ λ¨μ ν μ€νΈ con νμΈμ μμ±ν©λλ€.
κ°μ¬ ν΄μ...