反转在多个域上注入依赖项的正确方法 类
Inversify correct way to inject dependencies on many domain classes
我在弄清楚如何处理使用 typescript 制作的 rest web 服务上的依赖项和注入时遇到了麻烦。
我试图避免在我的域 classes 上依赖倒置遵循依赖倒置原则。这是目前的项目结构:
core/ (domain classes)
expressjs/ (web service context)
inversify/ (the injection magic for my domain classes should happen here)
other-modules/ (concrete interface implementations on 3rd party techs)
这是我的 classes 的示例:
interface DomainInterface {
foo(): void;
}
interface DomainService {
bar();
}
class ConcreteClass implements DomainInterface {
constructor(colaborator: DomainService) { }
foo() {
this.colaborator.bar();
...
}
}
现在我想通过 inversify 注入所有依赖项,但我不想修改我所有的域 classes 以通过 @injectable 装饰器使它们成为可注入的。
有一件事我正在做一个 class,其中包含对 inversify 模块的 @injectable 依赖,它为每个域继承 class 我需要被注入。例如:
@injectable()
class InverisfyConcreteClass extends ConcreteClass {
constructor(@inject(DomainService) colaborator: DomainService) {
super(colaborator);
}
}
但这让我想到了一个问题,我有很多域 classes,创建那么多 classes 会很疯狂。
另一种方法是创建一个 'Context' class,其中包含对所有 class 的引用,将它们绑定到容器并在需要时检索它们:
class InversifyInjectionContext {
container: Container;
bind() {
// bind all needed instances somehow (??)
}
concreteClass() {
return container.get<ConcreteClass>();
}
concreteDomainService() {
return container.get<AnyConcreteDomainService>();
}
}
现在的问题是我不知道如何创建实例并将它们正确地注册到 inversify 容器中,这样我才能在应用程序后检索它们。
解决这个问题的最佳方法是什么?
我终于通过在运行时装饰每个 class 解决了这个问题:
InversifyContext {
container: Container;
bindConcreteClass() {
decorate(injectable(), InverisfyConcreteClass);
decorate(inject("ColaboratorDomainService"), InverisfyConcreteClass, 0);
this.container.bind("InverisfyConcreteClass").to(DomainInterface);
}
bindColaboratorDomainService() {
decorate(injectable(), ColaboratorDomainService);
this.container.bind("ColaboratorDomainService").to(DomainService);
}
}
通过这种方式,我避免了对任何域依赖特定的注入技术class,让它们变得干净。
我在弄清楚如何处理使用 typescript 制作的 rest web 服务上的依赖项和注入时遇到了麻烦。 我试图避免在我的域 classes 上依赖倒置遵循依赖倒置原则。这是目前的项目结构:
core/ (domain classes)
expressjs/ (web service context)
inversify/ (the injection magic for my domain classes should happen here)
other-modules/ (concrete interface implementations on 3rd party techs)
这是我的 classes 的示例:
interface DomainInterface {
foo(): void;
}
interface DomainService {
bar();
}
class ConcreteClass implements DomainInterface {
constructor(colaborator: DomainService) { }
foo() {
this.colaborator.bar();
...
}
}
现在我想通过 inversify 注入所有依赖项,但我不想修改我所有的域 classes 以通过 @injectable 装饰器使它们成为可注入的。
有一件事我正在做一个 class,其中包含对 inversify 模块的 @injectable 依赖,它为每个域继承 class 我需要被注入。例如:
@injectable()
class InverisfyConcreteClass extends ConcreteClass {
constructor(@inject(DomainService) colaborator: DomainService) {
super(colaborator);
}
}
但这让我想到了一个问题,我有很多域 classes,创建那么多 classes 会很疯狂。
另一种方法是创建一个 'Context' class,其中包含对所有 class 的引用,将它们绑定到容器并在需要时检索它们:
class InversifyInjectionContext {
container: Container;
bind() {
// bind all needed instances somehow (??)
}
concreteClass() {
return container.get<ConcreteClass>();
}
concreteDomainService() {
return container.get<AnyConcreteDomainService>();
}
}
现在的问题是我不知道如何创建实例并将它们正确地注册到 inversify 容器中,这样我才能在应用程序后检索它们。
解决这个问题的最佳方法是什么?
我终于通过在运行时装饰每个 class 解决了这个问题:
InversifyContext {
container: Container;
bindConcreteClass() {
decorate(injectable(), InverisfyConcreteClass);
decorate(inject("ColaboratorDomainService"), InverisfyConcreteClass, 0);
this.container.bind("InverisfyConcreteClass").to(DomainInterface);
}
bindColaboratorDomainService() {
decorate(injectable(), ColaboratorDomainService);
this.container.bind("ColaboratorDomainService").to(DomainService);
}
}
通过这种方式,我避免了对任何域依赖特定的注入技术class,让它们变得干净。