Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular 2在构造函数外部注入依赖项_Angular_Typescript_Dependency Injection_Singleton - Fatal编程技术网

Angular 2在构造函数外部注入依赖项

Angular 2在构造函数外部注入依赖项,angular,typescript,dependency-injection,singleton,Angular,Typescript,Dependency Injection,Singleton,我目前正在研究Angular 2中的DI。我正在实现一个REST客户机,它对具体的数据类型使用一个泛型子类型,如下所示: class RESTClient<T>{ constructor() { var inj = ReflectiveInjector.resolveAndCreate([HTTP_PROVIDERS]); this.http = inj.get(Http); this.conf = RESTConfigura

我目前正在研究Angular 2中的DI。我正在实现一个REST客户机,它对具体的数据类型使用一个泛型子类型,如下所示:

class RESTClient<T>{
    constructor() {
        var inj =  ReflectiveInjector.resolveAndCreate([HTTP_PROVIDERS]);
        this.http = inj.get(Http);
        this.conf = RESTConfiguration;
    }
}
class BookClient extends RESTClient<Book>{      
    constructor(){
        // since I dont want to inject the HTTP Providers here, I'm using a custom    injector in the super class
        super();
    }
}

class WriterClient extends RESTClient<Writer>{      
    ...
    ...
}
应在主应用程序中进行如下配置:

initializeApp(){
  this.restconf.baseURL = "http://localhost:3004/";
}
bootstrap(MyApp, [RESTConfiguration]).then();
我现在想知道如何将RESTConfiguration的一个单例实例注入RESTService类,而不将其传递给构造函数。为了减少代码重复并避免typescript中的泛型问题,我希望构造函数保持无参数

在上面的示例(第一个代码段)中,我尝试使用我创建的ReflectVenjector注入配置,它为我提供了配置的自定义实例

我考虑了几种解决方案:

  • 通过使用服务或某些静态类属性使应用程序“全局注入器”可用来访问应用程序

  • 在我的配置中实现额外的单例逻辑

  • 找到在构造函数之外使用角度本机注入方法的方法吗


  • 我的思维中是否有错误,或者我是否误用了DI框架

    这将为这个问题提供一个解决方案,但在任何需要注入服务而不将其作为构造函数参数提供的情况下也会有所帮助

    我在另一篇帖子中看到了这个答案:

    您可以在AppModule类中配置Angular Injector,然后在任何其他类中使用它(您可以从任何类访问AppModule的成员)

    在AppModule中添加:

    export class AppModule { 
      /**
         * Allows for retrieving singletons using `AppModule.injector.get(MyService)`
         * This is good to prevent injecting the service as constructor parameter.
         */
        static injector: Injector;
        constructor(injector: Injector) {
            AppModule.injector = injector;
        }
    }
    
    然后在另一个类中,您可以执行以下操作(对于这个问题,请用Http替换MyService):

    这相当于使用:

    constructor(private myService: MyService){}
    

    在阅读了上面的链接问题之后,我觉得作者非常喜欢——我倾向于使用他的“肮脏的黑客”让类通过全局注入器——我绝对不想在20-30个类中重复代码。有什么办法可以解决这个问题吗?使用如上所示的定制喷油器的方式如何?然后,我可以直接将配置附加到我的服务,或者使其成为一个简单的静态类……这将创建一个独立的注入器。在任何模块中注册的提供程序以及为这些提供程序创建的实例都不会由该自定义注入器返回。您可以按照链接问题的答案进行操作-将Angular2应用程序的注入器传递给他人,并从该注入器获取服务。是的,这正在工作!那么这有多糟糕呢?(如果我没说错的话,你在上面的问题中称之为“肮脏的黑客”)。我假设这限制了子类的可测试性和可重用性?它隐藏了依赖关系,这使得代码更难阅读。这违背了熟悉Angular2DI工作原理的人的期望。它打破了离线编译,即生成静态代码来取代动态DI,从而提高性能并减少代码大小。它很管用!。在我的例子中:从另一个模块获取服务(不是懒惰的),然后全部解析实例!谢谢你。要添加@ronenmiller的建议,你可以将
    {provide:Injector,useValue:AppModule.Injector}
    添加到providers数组中。完成此操作后,您可以使用Injector类引用将Injector类直接注入到任何类构造函数中<代码>构造函数(injector:injector){}在一个超类中引用AppModule时,我得到了循环依赖关系,这个超类由一堆子类扩展而来。在我的例子中,AppModule.injector是未定义的。I get:无法读取Undeineduse angular 9的属性'get',此重设不起作用。我正在获取类型“typeof AppModule”上不存在属性“injector”。ts(2339)错误。
    @Injectable()
    export class MyClass{
        private myService;
    
        constructor(){
            this.myService = AppModule.injector.get(MyService);
        }
    }
    
    constructor(private myService: MyService){}