Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I Dependency Inject based on type and name, with AngularDart?

I have two services, each of which takes a different WebSocket as a constructor parameter. I'd like to use AngularDart's dependency injection to pass in the WebSocket connection, but I can't rely on types alone (as I have two WebSockets).

How can I annotate or specify which specific WebSocket connection should to each service?

Let's pretend I have:

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

and

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

Thanks!

like image 520
Seth Ladd Avatar asked Dec 27 '25 15:12

Seth Ladd


2 Answers

This problem is well understood if you look at GUICE. (https://code.google.com/p/google-guice/) The issue is that when you are retrieving an instance you need to have some sort of Key (this is what GUICE calls it). There are several ways you can get a Key.

In AngularJS, we simplified the issue and said that the parameter name is the Key. Since JS has no types in source code, that was really the only choice we had for a Key.

In AngualDart we have improved it and used the Type as the Key. This has the benefit that the parameter name is irrelevant. But it creates an issue that you can only ever inject one of each Type. For custom types it is not a big deal, but to have only one String configuration type becomes an issue.

The solution to this problem is to have annotations on top of types. So that Annotation + Type is the Key. Here is what that may look like:

NOTE: None of this exist yet, it is only a proposal, how it will be solved.

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: Since none of this is yet implemented, if you are passionate about helping AngularDart and would like to help make this a reality please contact me.

like image 123
Misko Hevery Avatar answered Dec 31 '25 06:12

Misko Hevery


I haven't seen anything about injection by type names. It's 'the' big improvment over JS that there aren't names anymore in Dart. You could embed the services or sockets in two different classes to distinuish them.

Without seeing some code it's somewhat hard to make suggestions.

Example

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());
}
like image 33
Günter Zöchbauer Avatar answered Dec 31 '25 07:12

Günter Zöchbauer



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!