2014-01-20 31 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}'); 
}