Angular Individual Service Injection - Decouple bootstrap service (#1457)

* change services to be individually injected into angular

* messing around with injection

* change angular bootstrapping to factory style

* formatting

* formatting

* fix imports

* fix build errors

* fix testsw

* fix tests

* fix compile errors
This commit is contained in:
Anthony Dresser
2018-05-23 16:51:02 -07:00
committed by GitHub
parent cd0f9b71c5
commit 1359354387
68 changed files with 1011 additions and 1116 deletions

View File

@@ -16,42 +16,48 @@ import { Extensions, IComponentRegistry } from 'sql/platform/dashboard/common/mo
import { ModelViewContent } from 'sql/parts/modelComponents/modelViewContent.component';
import { ModelComponentWrapper } from 'sql/parts/modelComponents/modelComponentWrapper.component';
import { ComponentHostDirective } from 'sql/parts/dashboard/common/componentHost.directive';
import { BOOTSTRAP_SERVICE_ID, IBootstrapService } from 'sql/services/bootstrap/bootstrapService';
import { IBootstrapParams } from 'sql/services/bootstrap/bootstrapService';
import { CommonServiceInterface } from 'sql/services/common/commonServiceInterface.service';
import { Registry } from 'vs/platform/registry/common/platform';
/* Model-backed components */
let extensionComponents = Registry.as<IComponentRegistry>(Extensions.ComponentContribution).getAllCtors();
@NgModule({
declarations: [
DialogContainer,
ModelViewContent,
ModelComponentWrapper,
ComponentHostDirective,
...extensionComponents
],
entryComponents: [DialogContainer, ...extensionComponents],
imports: [
FormsModule,
CommonModule,
BrowserModule
],
providers: [{ provide: APP_BASE_HREF, useValue: '/' }, CommonServiceInterface]
})
export class DialogModule {
export const DialogModule = (params, selector: string): any => {
@NgModule({
declarations: [
DialogContainer,
ModelViewContent,
ModelComponentWrapper,
ComponentHostDirective,
...extensionComponents
],
entryComponents: [DialogContainer, ...extensionComponents],
imports: [
FormsModule,
CommonModule,
BrowserModule
],
providers: [
{ provide: APP_BASE_HREF, useValue: '/' },
CommonServiceInterface,
{ provide: IBootstrapParams, useValue: params }
]
})
class ModuleClass {
constructor(
@Inject(forwardRef(() => ComponentFactoryResolver)) private _resolver: ComponentFactoryResolver,
@Inject(BOOTSTRAP_SERVICE_ID) private _bootstrapService: IBootstrapService,
@Inject(forwardRef(() => CommonServiceInterface)) bootstrap: CommonServiceInterface,
) {
constructor(
@Inject(forwardRef(() => ComponentFactoryResolver)) private _resolver: ComponentFactoryResolver,
@Inject(forwardRef(() => CommonServiceInterface)) bootstrap: CommonServiceInterface,
) {
}
ngDoBootstrap(appRef: ApplicationRef) {
const factoryWrapper: any = this._resolver.resolveComponentFactory(DialogContainer);
factoryWrapper.factory.selector = selector;
appRef.bootstrap(factoryWrapper);
}
}
ngDoBootstrap(appRef: ApplicationRef) {
const factoryWrapper: any = this._resolver.resolveComponentFactory(DialogContainer);
const uniqueSelector: string = this._bootstrapService.getUniqueSelector('dialog-modelview-container');
factoryWrapper.factory.selector = uniqueSelector;
appRef.bootstrap(factoryWrapper);
}
}
return ModuleClass;
};

View File

@@ -8,12 +8,11 @@
import 'vs/css!./media/dialogModal';
import { Component, AfterContentInit, ViewChild, Input, Inject, forwardRef, ElementRef } from '@angular/core';
import { ModelViewContent } from 'sql/parts/modelComponents/modelViewContent.component';
import { BootstrapParams } from 'sql/services/bootstrap/bootstrapParams';
import { BOOTSTRAP_SERVICE_ID, IBootstrapService } from 'sql/services/bootstrap/bootstrapService';
import { IBootstrapParams } from 'sql/services/bootstrap/bootstrapService';
import Event, { Emitter } from 'vs/base/common/event';
import { ComponentEventType } from '../../parts/modelComponents/interfaces';
export interface DialogComponentParams extends BootstrapParams {
export interface DialogComponentParams extends IBootstrapParams {
modelViewId: string;
validityChangedCallback: (valid: boolean) => void;
}
@@ -29,14 +28,12 @@ export interface DialogComponentParams extends BootstrapParams {
export class DialogContainer implements AfterContentInit {
private _onResize = new Emitter<void>();
public readonly onResize: Event<void> = this._onResize.event;
private _params: DialogComponentParams;
public modelViewId: string;
@ViewChild(ModelViewContent) private _modelViewContent: ModelViewContent;
constructor(
@Inject(forwardRef(() => ElementRef)) private _el: ElementRef,
@Inject(BOOTSTRAP_SERVICE_ID) bootstrapService: IBootstrapService) {
this._params = bootstrapService.getBootstrapParams(_el.nativeElement.tagName) as DialogComponentParams;
@Inject(IBootstrapParams) private _params: DialogComponentParams) {
this.modelViewId = this._params.modelViewId;
}

View File

@@ -10,7 +10,7 @@ import { Modal, IModalOptions } from 'sql/base/browser/ui/modal/modal';
import { attachModalDialogStyler } from 'sql/common/theme/styler';
import { Dialog, DialogButton } from 'sql/platform/dialog/dialogTypes';
import { DialogPane } from 'sql/platform/dialog/dialogPane';
import { IBootstrapService } from 'sql/services/bootstrap/bootstrapService';
import { Builder } from 'vs/base/browser/builder';
import { IPartService } from 'vs/workbench/services/part/common/partService';
import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService';
@@ -23,6 +23,7 @@ import { SIDE_BAR_BACKGROUND } from 'vs/workbench/common/theme';
import { localize } from 'vs/nls';
import Event, { Emitter } from 'vs/base/common/event';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
export class DialogModal extends Modal {
private _dialogPane: DialogPane;
@@ -41,7 +42,7 @@ export class DialogModal extends Modal {
@IWorkbenchThemeService private _themeService: IWorkbenchThemeService,
@ITelemetryService telemetryService: ITelemetryService,
@IContextKeyService contextKeyService: IContextKeyService,
@IBootstrapService private _bootstrapService: IBootstrapService
@IInstantiationService private _instantiationService: IInstantiationService
) {
super(_dialog.title, name, partService, telemetryService, contextKeyService, options);
}
@@ -99,7 +100,7 @@ export class DialogModal extends Modal {
});
this._dialogPane = new DialogPane(this._dialog.title, this._dialog.content,
valid => this._dialog.notifyValidityChanged(valid), this._bootstrapService);
valid => this._dialog.notifyValidityChanged(valid), this._instantiationService);
this._dialogPane.createBody(body);
}

View File

@@ -6,17 +6,21 @@
'use strict';
import 'vs/css!./media/dialogModal';
import { NgModuleRef } from '@angular/core';
import { IModalDialogStyles } from 'sql/base/browser/ui/modal/modal';
import { Dialog, DialogTab } from 'sql/platform/dialog/dialogTypes';
import { TabbedPanel, IPanelTab, IPanelView } from 'sql/base/browser/ui/panel/panel';
import { IBootstrapService } from 'sql/services/bootstrap/bootstrapService';
import { bootstrapAngular } from 'sql/services/bootstrap/bootstrapService';
import { DialogModule } from 'sql/platform/dialog/dialog.module';
import { DialogComponentParams } from 'sql/platform/dialog/dialogContainer.component';
import { Builder } from 'vs/base/browser/builder';
import { IThemable } from 'vs/platform/theme/common/styler';
import { Disposable } from 'vs/base/common/lifecycle';
import Event, { Emitter } from 'vs/base/common/event';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
export class DialogPane extends Disposable implements IThemable {
private _tabbedPanel: TabbedPanel;
@@ -35,7 +39,7 @@ export class DialogPane extends Disposable implements IThemable {
private _title: string,
private _content: string | DialogTab[],
private _validityChangedCallback: (valid: boolean) => void,
private _bootstrapService: IBootstrapService
private _instantiationService: IInstantiationService
) {
super();
this._tabs = [];
@@ -80,7 +84,7 @@ export class DialogPane extends Disposable implements IThemable {
* Bootstrap angular for the dialog's model view controller with the given model view ID
*/
private initializeModelViewContainer(bodyContainer: HTMLElement, modelViewId: string, tab?: DialogTab) {
this._bootstrapService.bootstrap(
this._instantiationService.invokeFunction(bootstrapAngular,
DialogModule,
bodyContainer,
'dialog-modelview-container',

View File

@@ -10,7 +10,7 @@ import { Modal, IModalOptions } from 'sql/base/browser/ui/modal/modal';
import { attachModalDialogStyler } from 'sql/common/theme/styler';
import { Wizard, Dialog, DialogButton, WizardPage } from 'sql/platform/dialog/dialogTypes';
import { DialogPane } from 'sql/platform/dialog/dialogPane';
import { IBootstrapService } from 'sql/services/bootstrap/bootstrapService';
import { bootstrapAngular } from 'sql/services/bootstrap/bootstrapService';
import { Button } from 'vs/base/browser/ui/button/button';
import { SIDE_BAR_BACKGROUND } from 'vs/workbench/common/theme';
import { Builder } from 'vs/base/browser/builder';
@@ -23,6 +23,7 @@ import { attachButtonStyler } from 'vs/platform/theme/common/styler';
import { localize } from 'vs/nls';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { Emitter } from 'vs/base/common/event';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
export class WizardModal extends Modal {
private _dialogPanes = new Map<WizardPage, DialogPane>();
@@ -47,7 +48,7 @@ export class WizardModal extends Modal {
@IWorkbenchThemeService private _themeService: IWorkbenchThemeService,
@ITelemetryService telemetryService: ITelemetryService,
@IContextKeyService contextKeyService: IContextKeyService,
@IBootstrapService private _bootstrapService: IBootstrapService
@IInstantiationService private _instantiationService: IInstantiationService
) {
super(_wizard.title, name, partService, telemetryService, contextKeyService, options);
}
@@ -116,7 +117,7 @@ export class WizardModal extends Modal {
}
private registerPage(page: WizardPage): void {
let dialogPane = new DialogPane(page.title, page.content, valid => page.notifyValidityChanged(valid), this._bootstrapService);
let dialogPane = new DialogPane(page.title, page.content, valid => page.notifyValidityChanged(valid), this._instantiationService);
dialogPane.createBody(this._body);
this._dialogPanes.set(page, dialogPane);
page.onUpdate(() => this.setButtonsForPage(this._wizard.currentPage));