Skip to content

Commit

Permalink
[CLEANUP beta] Deprecate owner.inject, drop implicit injections
Browse files Browse the repository at this point in the history
  • Loading branch information
snewcomer authored and mixonic committed Aug 22, 2021
1 parent 5593d7e commit cfad78f
Show file tree
Hide file tree
Showing 33 changed files with 110 additions and 1,113 deletions.
@@ -1,5 +1,4 @@
export function initialize(/* application */) {
// application.inject('route', 'foo', 'service:foo');
}

export default {
Expand Down
@@ -1,5 +1,4 @@
export function initialize(/* appInstance */) {
// appInstance.inject('route', 'foo', 'service:foo');
}

export default {
Expand Down
1 change: 0 additions & 1 deletion node-tests/fixtures/initializer/initializer-nested.js
@@ -1,5 +1,4 @@
export function initialize(/* application */) {
// application.inject('route', 'foo', 'service:foo');
}

export default {
Expand Down
1 change: 0 additions & 1 deletion node-tests/fixtures/initializer/initializer.js
@@ -1,5 +1,4 @@
export function initialize(/* application */) {
// application.inject('route', 'foo', 'service:foo');
}

export default {
Expand Down
@@ -1,5 +1,4 @@
export function initialize(/* appInstance */) {
// appInstance.inject('route', 'foo', 'service:foo');
}

export default {
Expand Down
@@ -1,5 +1,4 @@
export function initialize(/* appInstance */) {
// appInstance.inject('route', 'foo', 'service:foo');
}

export default {
Expand Down
77 changes: 4 additions & 73 deletions packages/@ember/-internals/container/lib/container.ts
Expand Up @@ -2,7 +2,7 @@ import { Factory, LookupOptions, Owner, setOwner } from '@ember/-internals/owner
import { dictionary, symbol } from '@ember/-internals/utils';
import { assert } from '@ember/debug';
import { DEBUG } from '@glimmer/env';
import Registry, { DebugRegistry, Injection } from './registry';
import Registry, { DebugRegistry } from './registry';

declare global {
export function gc(): void;
Expand Down Expand Up @@ -406,68 +406,6 @@ function instantiateFactory(
throw new Error('Could not create factory');
}

interface BuildInjectionsResult {
injections: { [key: string]: unknown };
isDynamic: boolean;
}

function processInjections(
container: Container,
injections: Injection[],
result: BuildInjectionsResult
) {
if (DEBUG) {
container.registry.validateInjections(injections);
}

let hash = result.injections;

for (let i = 0; i < injections.length; i++) {
let { property, specifier } = injections[i];

hash[property] = lookup(container, specifier);

if (!result.isDynamic) {
result.isDynamic = !isSingleton(container, specifier);
}
}
}

function buildInjections(
container: Container,
typeInjections: Injection[],
injections: Injection[]
): BuildInjectionsResult {
let injectionsHash = {};

setOwner(injectionsHash, container.owner!);

let result: BuildInjectionsResult = {
injections: injectionsHash,
isDynamic: false,
};

if (typeInjections !== undefined) {
processInjections(container, typeInjections, result);
}

if (injections !== undefined) {
processInjections(container, injections, result);
}

return result;
}

function injectionsFor(container: Container, fullName: string) {
let registry = container.registry;
let [type] = fullName.split(':');

let typeInjections = registry.getTypeInjections(type);
let injections = registry.getInjections(fullName);

return buildInjections(container, typeInjections, injections);
}

function destroyDestroyables(container: Container): void {
let cache = container.cache;
let keys = Object.keys(cache);
Expand Down Expand Up @@ -569,16 +507,9 @@ class FactoryManager<T, C> {
);
}

let props = this.injections;
if (props === undefined) {
let { injections, isDynamic } = injectionsFor(this.container, this.normalizedName);
setFactoryFor(injections, this);
props = injections;

if (!isDynamic) {
this.injections = injections;
}
}
let props = {};
setOwner(props, container.owner!);
setFactoryFor(props, this);

if (options !== undefined) {
props = Object.assign({}, props, options);
Expand Down
167 changes: 17 additions & 150 deletions packages/@ember/-internals/container/lib/registry.ts
@@ -1,6 +1,6 @@
import { Factory } from '@ember/-internals/owner';
import { dictionary, intern } from '@ember/-internals/utils';
import { assert } from '@ember/debug';
import { assert, deprecate } from '@ember/debug';
import { DEBUG } from '@glimmer/env';
import Container, { ContainerOptions, LazyInjection } from './container';

Expand All @@ -24,14 +24,12 @@ export interface KnownForTypeResult {

export interface IRegistry {
describe(fullName: string): string;
getInjections(fullName: string): Injection[];
getOption<K extends keyof TypeOptions>(
fullName: string,
optionName: K
): TypeOptions[K] | undefined;
getOptions(fullName: string): TypeOptions;
getOptionsForType(type: string): TypeOptions;
getTypeInjections(type: string): Injection[];
knownForType(type: string): KnownForTypeResult;
makeToString<T, C>(factory: Factory<T, C>, fullName: string): string;
normalizeFullName(fullName: string): string;
Expand Down Expand Up @@ -82,12 +80,10 @@ export default class Registry implements IRegistry {
resolver: Resolver | (Resolve & NotResolver) | null;
readonly fallback: IRegistry | null;
readonly registrations: { [key: string]: object };
readonly _injections: { [key: string]: Injection[] };
_localLookupCache: { [key: string]: object };
readonly _normalizeCache: { [key: string]: string };
readonly _options: { [key: string]: TypeOptions };
readonly _resolveCache: { [key: string]: object };
readonly _typeInjections: { [key: string]: Injection[] };
readonly _typeOptions: { [key: string]: TypeOptions };

constructor(options: RegistryOptions = {}) {
Expand All @@ -96,9 +92,6 @@ export default class Registry implements IRegistry {

this.registrations = dictionary(options.registrations || null);

this._typeInjections = dictionary(null);
this._injections = dictionary(null);

this._localLookupCache = Object.create(null);
this._normalizeCache = dictionary(null);
this._resolveCache = dictionary(null);
Expand Down Expand Up @@ -130,20 +123,6 @@ export default class Registry implements IRegistry {
@type InheritingDict
*/

/**
@private
@property _typeInjections
@type InheritingDict
*/

/**
@private
@property _injections
@type InheritingDict
*/

/**
@private
Expand Down Expand Up @@ -468,116 +447,32 @@ export default class Registry implements IRegistry {
}

/**
Used only via `injection`.
Provides a specialized form of injection, specifically enabling
all objects of one type to be injected with a reference to another
object.
For example, provided each object of type `controller` needed a `router`.
one would do the following:
```javascript
let registry = new Registry();
let container = registry.container();
registry.register('router:main', Router);
registry.register('controller:user', UserController);
registry.register('controller:post', PostController);
registry.typeInjection('controller', 'router', 'router:main');
let user = container.lookup('controller:user');
let post = container.lookup('controller:post');
user.router instanceof Router; //=> true
post.router instanceof Router; //=> true
// both controllers share the same router
user.router === post.router; //=> true
```
@private
@method typeInjection
@param {String} type
@param {String} property
@param {String} fullName
*/
typeInjection(type: string, property: string, fullName: string): void {
assert('fullName must be a proper full name', this.isValidFullName(fullName));

let fullNameType = fullName.split(':')[0];
assert(`Cannot inject a '${fullName}' on other ${type}(s).`, fullNameType !== type);

let injections = this._typeInjections[type] || (this._typeInjections[type] = []);

injections.push({ property, specifier: fullName });
}

/**
Defines injection rules.
These rules are used to inject dependencies onto objects when they
are instantiated.
Two forms of injections are possible:
This is deprecated in favor of explicit injection of dependencies.
* Injecting one fullName on another fullName
* Injecting one fullName on a type
Example:
```javascript
let registry = new Registry();
let container = registry.container();
registry.register('source:main', Source);
registry.register('model:user', User);
registry.register('model:post', Post);
// injecting one fullName on another fullName
// eg. each user model gets a post model
registry.injection('model:user', 'post', 'model:post');
// injecting one fullName on another type
registry.injection('model', 'source', 'source:main');
let user = container.lookup('model:user');
let post = container.lookup('model:post');
user.source instanceof Source; //=> true
post.source instanceof Source; //=> true
user.post instanceof Post; //=> true
// and both models share the same source
user.source === post.source; //=> true
Reference: https://deprecations.emberjs.com/v3.x#toc_implicit-injections
```
@private
@method injection
@param {String} factoryName
@param {String} property
@param {String} injectionName
@deprecated
*/
injection(fullName: string, property: string, injectionName: string) {
assert(
`Invalid injectionName, expected: 'type:name' got: ${injectionName}`,
this.isValidFullName(injectionName)
injection(fullName: string, property: string) {
deprecate(
`As of Ember 4.0.0, owner.inject no longer injects values into resolved instances, and calling the method has been deprecated. Since this method no longer does anything, it is fully safe to remove this injection. As an alternative to this API, you can refactor to explicitly inject \`${property}\` on \`${fullName}\`, or look it up directly using the \`getOwner\` API.`,
false,
{
id: 'remove-owner-inject',
until: '5.0.0',
url: 'https://deprecations.emberjs.com/v4.x#toc_implicit-injections',
for: 'ember-source',
since: {
enabled: '4.0.0',
},
}
);

let normalizedInjectionName = this.normalize(injectionName);

if (fullName.indexOf(':') === -1) {
return this.typeInjection(fullName, property, normalizedInjectionName);
}

assert('fullName must be a proper full name', this.isValidFullName(fullName));
let normalizedName = this.normalize(fullName);

let injections = this._injections[normalizedName] || (this._injections[normalizedName] = []);

injections.push({ property, specifier: normalizedInjectionName });
}

/**
Expand Down Expand Up @@ -612,34 +507,6 @@ export default class Registry implements IRegistry {
isValidFullName(fullName: string): boolean {
return VALID_FULL_NAME_REGEXP.test(fullName);
}

getInjections(fullName: string) {
let injections = this._injections[fullName];
if (this.fallback !== null) {
let fallbackInjections = this.fallback.getInjections(fullName);

if (fallbackInjections !== undefined) {
injections =
injections === undefined ? fallbackInjections : injections.concat(fallbackInjections);
}
}

return injections;
}

getTypeInjections(type: string): Injection[] {
let injections = this._typeInjections[type];
if (this.fallback !== null) {
let fallbackInjections = this.fallback.getTypeInjections(type);

if (fallbackInjections !== undefined) {
injections =
injections === undefined ? fallbackInjections : injections.concat(fallbackInjections);
}
}

return injections;
}
}

export declare class DebugRegistry extends Registry {
Expand Down

0 comments on commit cfad78f

Please sign in to comment.