4

I want to create a factory that is able to create a new instance of a class (MyClass, implementing an abstract class) that is using dependency injection.

I would like the factory to look like this:

Factory

export class Factory {

  public static makeMyClass() {
    return new MyClass();
  }

}

However, the EventAggregator is not injected into MyClass when I take this approach.

How can I do this?

Interface

export abstract class MyClassInterface {

  abstract connect();
  abstract disconnect();
  abstract send(message: string);

}

Class

@inject(EventAggregator)
export class MyClass {

  constructor(EventAggregator) {}

  connect() {}
  disconnect() {}
  send(message: string) {}

}

Thanks in advance!

Fabio
  • 11,892
  • 1
  • 25
  • 41
  • `@inject(NewInstance.of(MyClass))` is enough. If you really want to use a factory you have to inject the `EventAggregator` into the factory and then pass it to `MyClass` instance -> `new MyClass(this.eventAggregator);` – Fabio Jul 20 '17 at 16:16
  • 1
    Also, you've named the constructor parameter `EventAggregator`, which is the class name, that might cause issues. I recommend changing that to `eventAggregator` or `ea` or something. – Ashley Grant Jul 20 '17 at 16:18

1 Answers1

5

First Option

Use the NewInstance.of resolver:

import {inject, NewInstance} from 'aurelia-framework';

@inject(NewInstance.of(MyClass))
export class MyViewModel {
   constructor(myClass) {
     this.myClass = myClass; //myClass is always a new instance
   }
}

Second Option

Use a factory:

import {inject, EventAggregator} from 'aurelia-framework';

@inject(EventAggregator)
export class MyFactory {

  constructor(eventAggregator) {
    this.eventAggregator = eventAggregator;
  }

  public static createMyClass() {
    return new MyClass(this.eventAggregator);
  }
}

@inject(MyFactory)
export class MyViewModel {

  constructor(myFactory) {
    this.myClass = myFactory.createMyClass();
  }
}
martin
  • 825
  • 10
  • 15
Fabio
  • 11,892
  • 1
  • 25
  • 41
  • Thanks Fabio! Dependency injection is still complicating things for me a little, but I’m starting to understand the principles. Thanks for your quick answer! – Joshua Lee Tucker Jul 20 '17 at 21:39
  • @martin When using `@inject(NewInstance.of(MyClass))` how do I mock `MyClass` in a test ? – Bulkan Jan 04 '18 at 03:29
  • @Bulkan If you use the aurelia-testing library, you can use the `registerInstance` method on the `aurelia.container` object. There are several good examples in the documentation http://aurelia.io/docs/testing/components/ – martin Jan 04 '18 at 07:42
  • @martin I've tried this and I keep hitting this bug in https://github.com/aurelia/dependency-injection/issues/137 which I haven't been able to find a solution for – Bulkan Jan 10 '18 at 06:09