2014-01-20 34 views
3

我有兩個服務,每個服務都需要一個不同的 WebSocket作爲構造參數。我想使用AngularDart的依賴注入來傳入WebSocket連接,但我不能單獨依賴類型(因爲我有兩個WebSocket)。如何使用AngularDart依賴於類型和名稱的注入?

如何註釋或指定哪些特定的WebSocket連接應該爲每個服務?

讓我們假設我有:

class ServiceOne { 
    WebSocket socketOne; 
    ServiceOne(this.socketOne); 
} 

class ServiceTwo { 
    WebSocket socketTwo; // different connection 
    ServiceTwo(this.socketTwo); 
} 

謝謝!

+0

的WebSockets的打開應用程序啓動時,保持開放?您希望在構造函數引用它們的任何地方都可以使用它們?還是應該在注入websocket時打開連接? –

+0

我添加了一些例子。只要添加評論,如果這不是你想要的。 –

回答

3

我還沒有看到有關注入類型名稱的任何信息。這是對JS的重大改進,在Dart中不再有名字。 您可以將服務或套接字嵌入到兩個不同的類中以區分它們。

沒有看到一些代碼,有點難以提出建議。

library main; 

import 'dart:html'; 
import 'package:angular/angular.dart'; 
import 'package:di/di.dart'; 


/** 
* usage examples 
*/ 

class ServiceOne { 
    WebSocketWrapper1 socketOne; 
    ServiceOne(this.socketOne); 

    void doSomething() { 
    socketOne.ws.xxx(); 
    } 
} 

class ServiceTwo { 
    WebSocketWrapper2 socketTwo; // different connection 
    ServiceTwo(this.socketTwo); 

    void doSomething() { 
     socketTwo.ws.xxx(); 
    } 
    } 
}  

@NgController(
    selector: '[ng-controller=alert-demo-ctrl]', 
    publishAs: 'ctrl') 
class AlertDemoController { 
    WebSocketOnDemandWrapper1 _wsodw1; 

    AlertDemoController(this._wsodw1) { 
    } 

    String sendData() { 
    _wsodw1.ws.send("somedata"); 
    } 
} 

@NgController(
    selector: '[ng-controller=accordion-demo-ctrl]', 
    publishAs: 'ctrl') 
class AccordionDemoController { 
    WebSocketOnDemandWrapper2 _wsodw2; 

    AccordionDemoController(this._wsodw2) { 
    } 

    String sendData() { 
    _wsodw2.ws.send("somedata"); 
    } 
} 


/** 
* injectable WebSockets 
*/ 

class WebSocketWrapper1 { 
    WebSocket ws; 
    WebSocketWrapper1(this.ws); 
} 

class WebSocketWrapper2 { 
    WebSocket ws; 
    WebSocketWrapper2(this.ws); 
} 

class WebSocketOnDemandWrapper1 { 
    WebSocket ws; 
    WebSocketOnDemandWrapper1(){ 
    ws = new WebSocket('ws://127.0.0.1:1337/ws'); 
    } 
} 

class WebSocketOnDemandWrapper2 { 
    WebSocket ws; 
    WebSocketOnDemandWrapper2(){ 
    ws = new WebSocket('ws://127.0.0.1:3173/ws'); 
    } 
} 


class MyAppModule extends Module { 
    MyAppModule() { 
    type(ServiceOne); 
    type(ServiceTwo); 
    type(AlertDemoController); 
    type(AccordionDemoController); 
    type(WebSocketOnDemandWrapper1); // connect on demand 
    type(WebSocketOnDemandWrapper2); // connect on demand 

    // start connection on app startup and provide this connection when requested 
    value(WebSocketWrapper1, new WebSocketWrapper1(new WebSocket('ws://127.0.0.1:1337/ws'))); 
    value(WebSocketWrapper2, new WebSocketWrapper2(new WebSocket('ws://127.0.0.1:3173/ws'))); 
    } 
} 

void main() { 
    ngBootstrap(module: new MyAppModule()); 
} 
+0

我添加了一個簡單的例子。如果我不需要,我寧願不必創建WebSocket的子類。 –

4

如果你看看吉斯這個問題很好理解。 (https://code.google.com/p/google-guice/)問題是,當你檢索一個實例時,你需要有某種Key(這是GUICE所稱的)。有幾種方法可以獲得Key

在AngularJS中,我們簡化了問題,並說參數名稱是Key。由於JS在源代碼中沒有類型,所以對於Key這是我們唯一的選擇。

在AngualDart,我們改進了它並使用Type作爲Key。這具有參數名稱無關緊要的優點。但它造成了一個問題,你只能注入每個Type之一。對於自定義類型,這不是什麼大問題,但只有一個String配置類型成爲問題。

此問題的解決方案是在類型之上註釋。所以Annotation + TypeKey。以下是可能的樣子:

備註這些都不存在,它只是一個建議,它將如何解決。

class MyClass { 
    MyClass(@Url String url, @Secret String secret) { ... } 
} 

Module module = new Module(); 
module.value(key(String, [Url]), 'http://server.com/...'); 
module.value(key(String, [Secret]), 'A89B42C'); 

REQUEST由於沒有的,這是沒有實現,如果你是熱情幫助AngularDart和想幫助使這成爲現實,請與我聯繫。

+0

謝謝!我打開了https://github.com/angular/angular.dart/issues/422 –

+0

這實際上非常有用。 – markovuksanovic

+0

@ misko hevery什麼是最好的聯繫方式? :) – markovuksanovic

1

DI 0.0.34得到了使用註解不支持

註釋與參數的這種使用情況的特別支持。我不確定這是否仍在計劃中(https://github.com/angular/di.dart/issues/46

我還添加了一個示例,說明如何使用DI原語。 (不知道這是很有用處的尚未)

import 'package:di/di.dart'; 
import 'package:di/dynamic_injector.dart'; 

/** 
* Annotation used to mark classes for which static type factory must be 
* generated. For testing purposes not all classes are marked with this 
* annotation, some classes are included in @Injectables at the top. 
*/ 
class Injectable { 
    const Injectable(); 
} 

/** 
* Some dummy WebSocket class (just for demonstration) 
*/ 
@Injectable() 
class WebSocket { 
    String url; 
    WebSocket(this.url); 
} 

/** 
* Allows to mark an injectable as 'one' 
*/ 
class One { 
    const One(); 
} 

/** 
* Allows to mark an injectable as 'two' 
*/ 
class Two { 
    const Two(); 
} 

/** 
* A class that implements updates. 
* It needs a websocket marked as 'one' 
*/ 
class Updates { 
    WebSocket ws; 
    Updates(@One() this.ws); 
} 


/** 
* A class that implements chats. 
* It needs a websocket marked as 'two' 
*/ 
class Chat { 
    WebSocket ws; 
    Chat(@Two() this.ws); 
} 

/** 
* The application module 
*/ 
class AppModule extends Module { 
    AppModule() { 
    value(String, 'http://www.google.com', withAnnotation: AjaxUrl); 
    value(int, 8080, withAnnotation: ServerPort); 
    value(int, 1000); 
    factory(WebSocket, (Injector i) => new WebSocket('ws://game.example.com:12010/updates'), withAnnotation: One); 
    factory(WebSocket, (Injector i) => new WebSocket('ws://chat.example.com/games'), withAnnotation: Two); 
    type(Chat); 
    type(Updates); 
    } 

    Injector _injector; 
    Injector get injector { 
    if (_injector == null) { 
     _injector = new DynamicInjector(modules: [this]); 

     // Static injector => comment in and comment out above 
     //  _injector = new StaticInjector(modules: [this], 
     // typeFactories: type_factories_gen.typeFactories); 
    } 
    return _injector; 
    } 
} 

/** 
* Allows to mark a String as ajax url 
* Just to demonstrate how to use primitive types with DI 
*/ 
class AjaxUrl { 
    const AjaxUrl(); 
} 

/** 
* Allows to mark an int as server port 
* Just to demonstrate how to use primitive types with DI 
*/ 
class ServerPort { 
    const ServerPort(); 
} 


void main(List<String> args) { 
    var module = new AppModule(); 

    print('AjaxUrl: ${module.injector.get(String, AjaxUrl)}'); 
    print('ServerPort: ${module.injector.get(int, ServerPort)}'); 
    // primitives without annotation are not supported and throw an exception 
    // print('int: ${module.injector.get(int)}'); 
    print('Chat: ${module.injector.get(Chat).ws.url}'); 
    print('Updates: ${module.injector.get(Updates).ws.url}'); 
}