Skip to content
This repository was archived by the owner on Nov 30, 2019. It is now read-only.

Commit a65eca7

Browse files
committed
feat(pluginmanager): load container bindings before initializing the plugins
Added an extra ����entry in the plugin description file for defining container bindings which should be loaded before any plugin is initialized��
1 parent 9c0ac0d commit a65eca7

File tree

3 files changed

+117
-5
lines changed

3 files changed

+117
-5
lines changed

src/plugin/INotedPlugin.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { IPluginDescriptorFile } from './IPluginDescriptorFile';
2+
3+
/**
4+
* Contains informations about a noted plugin
5+
* which should be initialized after the container
6+
* bindings are loaded
7+
*
8+
* @export
9+
* @interface INotedPlugin
10+
*/
11+
export interface INotedPlugin {
12+
/**
13+
* The default export of the plugin
14+
*
15+
* @type {*}
16+
* @memberof INotedPlugin
17+
*/
18+
plugin: any;
19+
20+
/**
21+
* The plugin description file
22+
*
23+
* @type {IPluginDescriptorFile}
24+
* @memberof INotedPlugin
25+
*/
26+
pluginDescription: IPluginDescriptorFile;
27+
}

src/plugin/IPluginDescriptorFile.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,4 +50,13 @@ export interface IPluginDescriptorFile {
5050
* @memberof IPluginDescriptorFile
5151
*/
5252
main: string;
53+
54+
/**
55+
* Contains the path to additional container
56+
* bindings for the plugin
57+
*
58+
* @type {string}
59+
* @memberof IPluginDescriptorFile
60+
*/
61+
containerBindings?: string;
5362
}

src/plugin/PluginManager.ts

Lines changed: 81 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { EventManager } from '../event/EventManager';
99
import { IsNullOrUndefined } from '../Extras';
1010
import { Logger } from '../logger/Logger';
1111
import { InitializationSide } from './InitializationSide';
12+
import { INotedPlugin } from './INotedPlugin';
1213
import { IPlugin } from './IPlugin';
1314
import { IPluginDescriptorFile } from './IPluginDescriptorFile';
1415

@@ -71,6 +72,17 @@ export class PluginManager {
7172
*/
7273
private initializationSide: InitializationSide;
7374

75+
/**
76+
* Contains all noted plugins which should
77+
* be loaded after the container binding files
78+
* were bound
79+
*
80+
* @private
81+
* @type {INotedPlugin[]}
82+
* @memberof PluginManager
83+
*/
84+
private notedPlugins: INotedPlugin[];
85+
7486
/**
7587
* Creates an instance of PluginManager.
7688
* @param {Logger} logger The logger which should be used from the dependency injection container
@@ -103,6 +115,8 @@ export class PluginManager {
103115

104116
// Set the initialization side
105117
this.initializationSide = initializationSide;
118+
119+
this.notedPlugins = [];
106120
}
107121

108122
/**
@@ -174,9 +188,44 @@ export class PluginManager {
174188
continue;
175189
}
176190

191+
if (parsedPluginFile.containerBindings === undefined) {
192+
continue;
193+
}
194+
195+
if (parsedPluginFile.containerBindings.trim().length === 0) {
196+
this.logger.info(`The path to the container bindings for the plugin ${parsedPluginFile.name} is empty`);
197+
198+
continue;
199+
}
200+
201+
if (parsedPluginFile.containerBindings.includes('..')) {
202+
this.logger.warn(`The container bindings for the plugin ${parsedPluginFile.name} are not inside the plugin directory`);
203+
204+
continue;
205+
}
206+
207+
try {
208+
this.loadContainerBindings(
209+
pluginDirectory,
210+
parsedPluginFile.containerBindings,
211+
);
212+
213+
this.notedPlugins.push({
214+
plugin,
215+
pluginDescription: parsedPluginFile,
216+
});
217+
} catch (error) {
218+
this.logger.error(
219+
`Could not load the container bindings for the plugin ${parsedPluginFile.name}`,
220+
error,
221+
);
222+
}
223+
}
224+
225+
this.notedPlugins.forEach((notedPlugin) => {
177226
const pluginInstance = this.getPluginInstance(
178-
parsedPluginFile,
179-
plugin,
227+
notedPlugin.pluginDescription,
228+
notedPlugin.plugin,
180229
);
181230

182231
try {
@@ -185,14 +234,17 @@ export class PluginManager {
185234
this.initializationSide,
186235
);
187236
} catch (error) {
188-
this.logger.error(`Could not call onInit for plugin "${pluginDirectory}"`, error);
237+
this.logger.error(
238+
`Could not call onInit for plugin "${notedPlugin.pluginDescription.name}"`,
239+
error,
240+
);
189241

190-
continue;
242+
return;
191243
}
192244

193245
// Add the plugin to the managed plugins
194246
this.plugins.push(pluginInstance);
195-
}
247+
});
196248
}
197249

198250
/**
@@ -327,6 +379,30 @@ export class PluginManager {
327379
return pluginFunction;
328380
}
329381

382+
/**
383+
* Loads the container bindings for the given plugin
384+
*
385+
* @private
386+
* @param {string} pluginDirectory The path to the plugin directory
387+
* @param {IPluginDescriptorFile} parsedPluginFile The parsed plugin description file
388+
* @memberof PluginManager
389+
*/
390+
private loadContainerBindings(
391+
pluginDirectory: string,
392+
containerBindingsPath: string,
393+
) {
394+
const resolvedContainerBindingsPath = resolve(
395+
pluginDirectory,
396+
containerBindingsPath,
397+
);
398+
399+
const loadedContainerBindings = require(
400+
resolvedContainerBindingsPath,
401+
);
402+
403+
loadedContainerBindings(this.container);
404+
}
405+
330406
/**
331407
* Returns an plugin instance which was created with
332408
* the help of the dependency injection container

0 commit comments

Comments
 (0)