Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ root = true

# Unix-style newlines with a newline ending every file
[*]
end_of_line = crlf
end_of_line = lf
insert_final_newline = true

# 2 space indentation
Expand Down
4 changes: 2 additions & 2 deletions src/container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@ export class Container {
/**
* Gets the resolver for the particular key, if it has been registered.
* @param key The key that identifies the dependency at resolution time; usually a constructor function.
* @return Returns the resolver, if registred, otherwise undefined.
* @return Returns the resolver, if registered, otherwise undefined.
*/
public getResolver<
TStrategyKey extends keyof StrategyState<TBase, TImpl, TArgs>,
Expand All @@ -436,7 +436,7 @@ export class Container {
TArgs extends Args<TBase> = Args<TBase>
>(
key: PrimitiveOrDependencyCtorOrFunctor<TBase, TImpl, TArgs>
): StrategyResolver<TBase, TImpl, TArgs, TStrategyKey> {
): StrategyResolver<TBase, TImpl, TArgs, TStrategyKey> | undefined {
return this._resolvers.get(key);
}

Expand Down
9 changes: 8 additions & 1 deletion src/resolvers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,14 @@ export class NewInstance<

let fn = this.key;
const resolver = container.getResolver(fn);
if (resolver && resolver.strategy === 3) {
// If the key has not been previously registered, register it so that the "new instance" is not the first instance.
if (resolver === undefined) {
if (typeof fn === 'function') {
container.autoRegister(fn as DependencyCtor<TBase, TImpl, TArgs>);
} else {
container.get(fn);
}
} else if (resolver.strategy === 3) {
fn = resolver.state;
}

Expand Down
129 changes: 123 additions & 6 deletions test/resolver.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,26 @@ describe('resolver', () => {

class Dependency { }

it('get a new instance of a dependency, without regard for existing instances in the container', () => {
const container = new Container();
const logger = container.get(Logger);
const newLogger = container.get(NewInstance.of(Logger));

expect(logger).toEqual(jasmine.any(Logger));
expect(newLogger).toEqual(jasmine.any(Logger));
expect(newLogger).not.toBe(logger);
});

it('new instance of a dependency does not become the default instance in the container', () => {
const container = new Container();
const newLogger = container.get(NewInstance.of(Logger));
const logger = container.get(Logger);

expect(logger).toEqual(jasmine.any(Logger));
expect(newLogger).toEqual(jasmine.any(Logger));
expect(newLogger).not.toBe(logger);
});

it('inject a new instance of a dependency, without regard for existing instances in the container', () => {
class App1 {
public static inject() { return [NewInstance.of(Logger)]; }
Expand All @@ -434,8 +454,8 @@ describe('resolver', () => {
}

const container = new Container();
const logger = container.get(Logger);
const app1 = container.get(App1);
const logger = container.get(Logger);

expect(app1.logger).toEqual(jasmine.any(Logger));
expect(app1.logger).not.toBe(logger);
Expand All @@ -449,13 +469,110 @@ describe('resolver', () => {
}

const container = new Container();
const app1 = container.get(App1);
const logger = container.get(Logger);

expect(app1.logger).toEqual(jasmine.any(Logger));
expect(app1.logger).not.toBe(logger);
});

it('decorate with inject(NewInstance.of()) to inject a new instance of a dependency', () => {
type ILogger = Logger;

@autoinject
class App1 {
constructor(
@inject(NewInstance.of(Logger)) public logger: ILogger,
) {
}
}

const container = new Container();
const app1 = container.get(App1);
const logger = container.get(Logger);

expect(app1.logger).toEqual(jasmine.any(Logger));
expect(app1.logger).not.toBe(logger);
});

it('decorate with inject(NewInstance.of()) to inject a new instance of a dependency (inject default elsewhere)',
() => {
type ILogger = Logger;

@autoinject
class Child {
constructor(
public logger: Logger,
) { }
}

@autoinject
class App1 {
constructor(
@inject(NewInstance.of(Logger)) public logger: ILogger,
public child: Child,
) {
}
}

const container = new Container();
const app1 = container.get(App1);
const logger = container.get(Logger);

expect(app1.logger).toEqual(jasmine.any(Logger));
expect(app1.logger).not.toBe(logger);
});

it('decorate to inject a new instance of a dependency (inject default elsewhere)', () => {
@autoinject
class Child {
constructor(
public logger: Logger,
) { }
}

@autoinject
class App1 {
constructor(
@newInstance() public logger: Logger,
public child: Child,
) {
}
}

const container = new Container();
const app1 = container.get(App1);
const logger = container.get(Logger);

expect(app1.logger).toEqual(jasmine.any(Logger));
expect(app1.logger).not.toBe(logger);
});

it('default instance can be injected when newInstance injected in parent', () => {
@autoinject
class Child {
constructor(
public logger: Logger,
) { }
}

@autoinject
class App1 {
constructor(
@newInstance() public logger: Logger,
public child: Child,
) {
}
}

const container = new Container();
const app1 = container.get(App1);
const logger = container.get(Logger);

expect(app1.child).toEqual(jasmine.any(Child));
expect(app1.child.logger).toBe(logger);
});

it('decorate to inject a new instance of a dependency under a new key', () => {
@autoinject()
class App1 {
Expand All @@ -464,8 +581,8 @@ describe('resolver', () => {
}

const container = new Container();
const logger = container.get<string, Logger>('akey');
const app1 = container.get(App1);
const logger = container.get<string, Logger>('akey');

expect(app1.logger).toEqual(jasmine.any(Logger));
expect(app1.logger).not.toEqual(logger);
Expand All @@ -479,8 +596,8 @@ describe('resolver', () => {
}

const container = new Container();
const logger = container.get(Logger);
const app1 = container.get(App1);
const logger = container.get(Logger);

expect(app1.logger).toEqual(jasmine.any(Logger));
expect(app1.logger).not.toBe(logger);
Expand All @@ -495,8 +612,8 @@ describe('resolver', () => {
}

const container = new Container();
const logger = container.get(Logger);
const app1 = container.get(App1);
const logger = container.get(Logger);

expect(app1.logger).toEqual(jasmine.any(Logger));
expect(app1.logger).not.toBe(logger);
Expand All @@ -511,8 +628,8 @@ describe('resolver', () => {
}

const container = new Container();
const logger = container.get(Logger);
const app1 = container.get(App1);
const logger = container.get(Logger);

expect(app1.logger).toEqual(jasmine.any(Logger));
expect(app1.logger).not.toBe(logger);
Expand All @@ -526,8 +643,8 @@ describe('resolver', () => {
}

const container = new Container();
const logger = container.get(Logger);
const app1 = container.get(App1);
const logger = container.get(Logger);

expect(app1.logger).toEqual(jasmine.any(Logger));
expect(app1.logger).not.toBe(logger);
Expand Down