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

@@ -17,15 +17,22 @@ import { IGridDataRow, VirtualizedCollection } from 'angular2-slickgrid';
import { IGridDataSet } from 'sql/parts/grid/common/interfaces';
import * as Services from 'sql/parts/grid/services/sharedServices';
import { IBootstrapService, BOOTSTRAP_SERVICE_ID } from 'sql/services/bootstrap/bootstrapService';
import { EditDataComponentParams } from 'sql/services/bootstrap/bootstrapParams';
import { IEditDataComponentParams } from 'sql/services/bootstrap/bootstrapParams';
import { GridParentComponent } from 'sql/parts/grid/views/gridParentComponent';
import { EditDataGridActionProvider } from 'sql/parts/grid/views/editData/editDataGridActions';
import { error } from 'sql/base/common/log';
import { clone } from 'sql/base/common/objects';
import { IQueryEditorService } from 'sql/parts/query/common/queryEditorService';
import { IBootstrapParams } from 'sql/services/bootstrap/bootstrapService';
import { INotificationService } from 'vs/platform/notification/common/notification';
import Severity from 'vs/base/common/severity';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
import { KeyCode } from 'vs/base/common/keyCodes';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
@@ -59,8 +66,6 @@ export class EditDataComponent extends GridParentComponent implements OnInit, On
private removingNewRow: boolean;
private rowIdMappings: { [gridRowId: number]: number } = {};
private notificationService: INotificationService;
// Edit Data functions
public onActiveCellChanged: (event: { row: number, column: number }) => void;
public onCellEditEnd: (event: { row: number, column: number, newValue: any }) => void;
@@ -75,14 +80,20 @@ export class EditDataComponent extends GridParentComponent implements OnInit, On
constructor(
@Inject(forwardRef(() => ElementRef)) el: ElementRef,
@Inject(forwardRef(() => ChangeDetectorRef)) cd: ChangeDetectorRef,
@Inject(BOOTSTRAP_SERVICE_ID) bootstrapService: IBootstrapService
@Inject(IBootstrapParams) params: IEditDataComponentParams,
@Inject(IInstantiationService) private instantiationService: IInstantiationService,
@Inject(INotificationService) private notificationService: INotificationService,
@Inject(IContextMenuService) contextMenuService: IContextMenuService,
@Inject(IKeybindingService) keybindingService: IKeybindingService,
@Inject(IContextKeyService) contextKeyService: IContextKeyService,
@Inject(IConfigurationService) configurationService: IConfigurationService,
@Inject(IClipboardService) clipboardService: IClipboardService,
@Inject(IQueryEditorService) queryEditorService: IQueryEditorService
) {
super(el, cd, bootstrapService);
super(el, cd, contextMenuService, keybindingService, contextKeyService, configurationService, clipboardService, queryEditorService);
this._el.nativeElement.className = 'slickgridContainer';
let editDataParameters: EditDataComponentParams = this._bootstrapService.getBootstrapParams(this._el.nativeElement.tagName);
this.dataService = editDataParameters.dataService;
this.actionProvider = this._bootstrapService.instantiationService.createInstance(EditDataGridActionProvider, this.dataService, this.onGridSelectAll(), this.onDeleteRow(), this.onRevertRow());
this.notificationService = bootstrapService.notificationService;
this.dataService = params.dataService;
this.actionProvider = this.instantiationService.createInstance(EditDataGridActionProvider, this.dataService, this.onGridSelectAll(), this.onDeleteRow(), this.onRevertRow());
}
/**

View File

@@ -4,42 +4,48 @@
*--------------------------------------------------------------------------------------------*/
import { ApplicationRef, ComponentFactoryResolver, NgModule, Inject, forwardRef } from '@angular/core';
import { ApplicationRef, ComponentFactoryResolver, NgModule, Inject, forwardRef, Type } from '@angular/core';
import { CommonModule } from '@angular/common';
import { BrowserModule } from '@angular/platform-browser';
import { IBootstrapService, BOOTSTRAP_SERVICE_ID } from 'sql/services/bootstrap/bootstrapService';
import { EditDataComponent, EDITDATA_SELECTOR } from 'sql/parts/grid/views/editData/editData.component';
import { SlickGrid } from 'angular2-slickgrid';
import { IBootstrapParams } from 'sql/services/bootstrap/bootstrapService';
@NgModule({
export const EditDataModule = (params: IBootstrapParams, selector: string): Type<any> => {
imports: [
CommonModule,
BrowserModule
],
@NgModule({
declarations: [
EditDataComponent,
SlickGrid
],
imports: [
CommonModule,
BrowserModule
],
entryComponents: [
EditDataComponent
]
})
export class EditDataModule {
declarations: [
EditDataComponent,
SlickGrid
],
constructor(
@Inject(forwardRef(() => ComponentFactoryResolver)) private _resolver: ComponentFactoryResolver,
@Inject(BOOTSTRAP_SERVICE_ID) private _bootstrapService: IBootstrapService
) {
entryComponents: [
EditDataComponent
],
providers: [
{ provide: IBootstrapParams, useValue: params }
]
})
class ModuleClass {
constructor(
@Inject(forwardRef(() => ComponentFactoryResolver)) private _resolver: ComponentFactoryResolver
) {
}
ngDoBootstrap(appRef: ApplicationRef) {
const factory = this._resolver.resolveComponentFactory(EditDataComponent);
(<any>factory).factory.selector = selector;
appRef.bootstrap(factory);
}
}
ngDoBootstrap(appRef: ApplicationRef) {
const factory = this._resolver.resolveComponentFactory(EditDataComponent);
const uniqueSelector: string = this._bootstrapService.getUniqueSelector(EDITDATA_SELECTOR);
(<any>factory).factory.selector = uniqueSelector;
appRef.bootstrap(factory);
}
}
return ModuleClass;
};

View File

@@ -24,8 +24,8 @@ import * as actions from 'sql/parts/grid/views/gridActions';
import * as Services from 'sql/parts/grid/services/sharedServices';
import * as GridContentEvents from 'sql/parts/grid/common/gridContentEvents';
import { ResultsVisibleContext, ResultsGridFocussedContext, ResultsMessagesFocussedContext, QueryEditorVisibleContext } from 'sql/parts/query/common/queryContext';
import { IBootstrapService } from 'sql/services/bootstrap/bootstrapService';
import { error } from 'sql/base/common/log';
import { IQueryEditorService } from 'sql/parts/query/common/queryEditorService';
import { IAction } from 'vs/base/common/actions';
import { ResolvedKeybinding } from 'vs/base/common/keyCodes';
@@ -35,6 +35,8 @@ import { IContextMenuService } from 'vs/platform/contextview/browser/contextView
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { AutoColumnSize } from 'sql/base/browser/ui/table/plugins/autoSizeColumns.plugin';
import { DragCellSelectionModel } from 'sql/base/browser/ui/table/plugins/dragCellSelectionModel.plugin';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
export abstract class GridParentComponent {
@@ -63,9 +65,6 @@ export abstract class GridParentComponent {
// FIELDS
// Service for interaction with the IQueryModel
protected dataService: DataService;
protected keybindingService: IKeybindingService;
protected scopedContextKeyService: IContextKeyService;
protected contextMenuService: IContextMenuService;
protected actionProvider: actions.GridActionProvider;
protected toDispose: IDisposable[];
@@ -114,7 +113,12 @@ export abstract class GridParentComponent {
constructor(
protected _el: ElementRef,
protected _cd: ChangeDetectorRef,
protected _bootstrapService: IBootstrapService
protected contextMenuService: IContextMenuService,
protected keybindingService: IKeybindingService,
protected contextKeyService: IContextKeyService,
protected configurationService: IConfigurationService,
protected clipboardService: IClipboardService,
protected queryEditorService: IQueryEditorService
) {
this.toDispose = [];
}
@@ -122,8 +126,8 @@ export abstract class GridParentComponent {
protected baseInit(): void {
const self = this;
this.initShortcutsBase();
if (this._bootstrapService.configurationService) {
let sqlConfig = this._bootstrapService.configurationService.getValue('sql');
if (this.configurationService) {
let sqlConfig = this.configurationService.getValue('sql');
if (sqlConfig) {
this._messageActive = sqlConfig['messagesDefaultOpen'];
}
@@ -181,10 +185,7 @@ export abstract class GridParentComponent {
}
});
this.contextMenuService = this._bootstrapService.contextMenuService;
this.keybindingService = this._bootstrapService.keybindingService;
this.bindKeys(this._bootstrapService.contextKeyService);
this.bindKeys(this.contextKeyService);
}
/*
@@ -201,7 +202,7 @@ export abstract class GridParentComponent {
this.queryEditorVisible = QueryEditorVisibleContext.bindTo(contextKeyService);
this.queryEditorVisible.set(true);
let gridContextKeyService = this._bootstrapService.contextKeyService.createScoped(this._el.nativeElement);
let gridContextKeyService = this.contextKeyService.createScoped(this._el.nativeElement);
this.toDispose.push(gridContextKeyService);
this.resultsVisibleContextKey = ResultsVisibleContext.bindTo(gridContextKeyService);
this.resultsVisibleContextKey.set(true);
@@ -246,7 +247,7 @@ export abstract class GridParentComponent {
private copySelection(): void {
let messageText = this.getMessageText();
if (messageText.length > 0) {
this._bootstrapService.clipboardService.writeText(messageText);
this.clipboardService.writeText(messageText);
} else {
let activeGrid = this.activeGrid;
let selection = this.slickgrids.toArray()[activeGrid].getSelectedRanges();
@@ -269,7 +270,7 @@ export abstract class GridParentComponent {
messageText = this.getMessageText();
}
if (messageText.length > 0) {
this._bootstrapService.clipboardService.writeText(messageText);
this.clipboardService.writeText(messageText);
}
}
@@ -533,7 +534,7 @@ export abstract class GridParentComponent {
private handleQueryPlanLink(cellRef: string, value: string): void {
const self = this;
$(cellRef).children('.xmlLink').click(function (): void {
self._bootstrapService.queryEditorService.newQueryPlanEditor(value);
self.queryEditorService.newQueryPlanEditor(value);
});
}

View File

@@ -14,7 +14,6 @@ import { Taskbar } from 'sql/base/browser/ui/taskbar/taskbar';
import { Checkbox } from 'sql/base/browser/ui/checkbox/checkbox';
import { ComponentHostDirective } from 'sql/parts/dashboard/common/componentHost.directive';
import { IGridDataSet } from 'sql/parts/grid/common/interfaces';
import { IBootstrapService, BOOTSTRAP_SERVICE_ID } from 'sql/services/bootstrap/bootstrapService';
import { IInsightData, IInsightsView, IInsightsConfig } from 'sql/parts/dashboard/widgets/insights/interfaces';
import { Extensions, IInsightRegistry } from 'sql/platform/dashboard/common/insightRegistry';
import { QueryEditor } from 'sql/parts/query/editor/queryEditor';
@@ -24,6 +23,8 @@ import { IChartViewActionContext, CopyAction, CreateInsightAction, SaveImageActi
import * as WorkbenchUtils from 'sql/workbench/common/sqlWorkbenchUtils';
import * as Constants from 'sql/parts/query/common/constants';
import { SelectBox as AngularSelectBox } from 'sql/base/browser/ui/selectBox/selectBox.component';
import { IQueryModelService } from 'sql/parts/query/execution/queryModel';
import { IClipboardService } from 'sql/platform/clipboard/common/clipboardService';
/* Insights */
import {
@@ -40,6 +41,13 @@ import { mixin } from 'vs/base/common/objects';
import * as paths from 'vs/base/common/paths';
import * as pfs from 'vs/base/node/pfs';
import { ISelectData } from 'vs/base/browser/ui/selectBox/selectBox';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IWindowsService, IWindowService } from 'vs/platform/windows/common/windows';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
const insightRegistry = Registry.as<IInsightRegistry>(Extensions.InsightContribution);
@@ -94,8 +102,17 @@ export class ChartViewerComponent implements OnInit, OnDestroy, IChartViewAction
constructor(
@Inject(forwardRef(() => ComponentFactoryResolver)) private _componentFactoryResolver: ComponentFactoryResolver,
@Inject(forwardRef(() => ViewContainerRef)) private _viewContainerRef: ViewContainerRef,
@Inject(BOOTSTRAP_SERVICE_ID) private _bootstrapService: IBootstrapService,
@Inject(forwardRef(() => ChangeDetectorRef)) private _cd: ChangeDetectorRef
@Inject(forwardRef(() => ChangeDetectorRef)) private _cd: ChangeDetectorRef,
@Inject(IInstantiationService) private instantiationService: IInstantiationService,
@Inject(INotificationService) private notificationService: INotificationService,
@Inject(IContextMenuService) private contextMenuService: IContextMenuService,
@Inject(IClipboardService) private clipboardService: IClipboardService,
@Inject(IConfigurationService) private configurationService: IConfigurationService,
@Inject(IWindowsService) private windowsService: IWindowsService,
@Inject(IWorkspaceContextService) private workspaceContextService: IWorkspaceContextService,
@Inject(IWindowService) private windowService: IWindowService,
@Inject(IQueryModelService) private queryModelService: IQueryModelService,
@Inject(IWorkbenchEditorService) private editorService: IWorkbenchEditorService
) {
this.setDefaultChartConfig();
}
@@ -116,8 +133,8 @@ export class ChartViewerComponent implements OnInit, OnDestroy, IChartViewAction
private getDefaultChartType(): string {
let defaultChartType = Constants.chartTypeHorizontalBar;
if (this._bootstrapService.configurationService) {
let chartSettings = WorkbenchUtils.getSqlConfigSection(this._bootstrapService.configurationService, 'chart');
if (this.configurationService) {
let chartSettings = WorkbenchUtils.getSqlConfigSection(this.configurationService, 'chart');
// Only use the value if it's a known chart type. Ideally could query this dynamically but can't figure out how
if (chartSettings && Constants.allChartTypes.indexOf(chartSettings[Constants.defaultChartType]) > -1) {
defaultChartType = chartSettings[Constants.defaultChartType];
@@ -127,12 +144,12 @@ export class ChartViewerComponent implements OnInit, OnDestroy, IChartViewAction
}
private _initActionBar() {
this._createInsightAction = this._bootstrapService.instantiationService.createInstance(CreateInsightAction);
this._copyAction = this._bootstrapService.instantiationService.createInstance(CopyAction);
this._saveAction = this._bootstrapService.instantiationService.createInstance(SaveImageAction);
this._createInsightAction = this.instantiationService.createInstance(CreateInsightAction);
this._copyAction = this.instantiationService.createInstance(CopyAction);
this._saveAction = this.instantiationService.createInstance(SaveImageAction);
let taskbar = <HTMLElement>this.taskbarContainer.nativeElement;
this._actionBar = new Taskbar(taskbar, this._bootstrapService.contextMenuService);
this._actionBar = new Taskbar(taskbar, this.contextMenuService);
this._actionBar.context = this;
this._actionBar.setContent([
{ action: this._createInsightAction },
@@ -180,7 +197,7 @@ export class ChartViewerComponent implements OnInit, OnDestroy, IChartViewAction
return;
}
this._bootstrapService.clipboardService.writeImageDataUrl(data);
this.clipboardService.writeImageDataUrl(data);
}
public saveChart(): void {
@@ -197,8 +214,8 @@ export class ChartViewerComponent implements OnInit, OnDestroy, IChartViewAction
this.showError(err.message);
} else {
let fileUri = URI.from({ scheme: PathUtilities.FILE_SCHEMA, path: filePath });
this._bootstrapService.windowsService.openExternal(fileUri.toString());
this._bootstrapService.notificationService.notify({
this.windowsService.openExternal(fileUri.toString());
this.notificationService.notify({
severity: Severity.Error,
message: nls.localize('chartSaved', 'Saved Chart to path: {0}', filePath)
});
@@ -209,9 +226,9 @@ export class ChartViewerComponent implements OnInit, OnDestroy, IChartViewAction
}
private promptForFilepath(): Thenable<string> {
let filepathPlaceHolder = PathUtilities.resolveCurrentDirectory(this.getActiveUriString(), PathUtilities.getRootPath(this._bootstrapService.workspaceContextService));
let filepathPlaceHolder = PathUtilities.resolveCurrentDirectory(this.getActiveUriString(), PathUtilities.getRootPath(this.workspaceContextService));
filepathPlaceHolder = paths.join(filepathPlaceHolder, 'chart.png');
return this._bootstrapService.windowService.showSaveDialog({
return this.windowService.showSaveDialog({
title: nls.localize('chartViewer.saveAsFileTitle', 'Choose Results File'),
defaultPath: paths.normalize(filepathPlaceHolder, true)
});
@@ -230,7 +247,7 @@ export class ChartViewerComponent implements OnInit, OnDestroy, IChartViewAction
}
let uri: URI = URI.parse(uriString);
let dataService = this._bootstrapService.queryModelService.getDataService(uriString);
let dataService = this.queryModelService.getDataService(uriString);
if (!dataService) {
this.showError(nls.localize('createInsightNoDataService', 'Cannot create insight, backing data model not found'));
return;
@@ -259,7 +276,7 @@ export class ChartViewerComponent implements OnInit, OnDestroy, IChartViewAction
}
private showError(errorMsg: string) {
this._bootstrapService.notificationService.notify({
this.notificationService.notify({
severity: Severity.Error,
message: errorMsg
});
@@ -274,7 +291,7 @@ export class ChartViewerComponent implements OnInit, OnDestroy, IChartViewAction
}
private getActiveUriString(): string {
let editorService = this._bootstrapService.editorService;
let editorService = this.editorService;
let editor = editorService.getActiveEditor();
if (editor && editor instanceof QueryEditor) {
let queryEditor: QueryEditor = editor;

View File

@@ -22,16 +22,22 @@ import * as Services from 'sql/parts/grid/services/sharedServices';
import { IGridIcon, IMessage, IGridDataSet } from 'sql/parts/grid/common/interfaces';
import { GridParentComponent } from 'sql/parts/grid/views/gridParentComponent';
import { GridActionProvider } from 'sql/parts/grid/views/gridActions';
import { IBootstrapService, BOOTSTRAP_SERVICE_ID } from 'sql/services/bootstrap/bootstrapService';
import { QueryComponentParams } from 'sql/services/bootstrap/bootstrapParams';
import { IQueryComponentParams } from 'sql/services/bootstrap/bootstrapParams';
import { error } from 'sql/base/common/log';
import { TabChild } from 'sql/base/browser/ui/panel/tab.component';
import { clone } from 'sql/base/common/objects';
import { IQueryEditorService } from 'sql/parts/query/common/queryEditorService';
import * as strings from 'vs/base/common/strings';
import * as DOM from 'vs/base/browser/dom';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { KeyCode } from 'vs/base/common/keyCodes';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
export const QUERY_SELECTOR: string = 'query-component';
@@ -149,7 +155,7 @@ export class QueryComponent extends GridParentComponent implements OnInit, OnDes
public showChartRequested: EventEmitter<IGridDataSet> = new EventEmitter<IGridDataSet>();
public goToNextQueryOutputTabRequested: EventEmitter<void> = new EventEmitter<void>();
@Input() public queryParameters: QueryComponentParams;
@Input() public queryParameters: IQueryComponentParams;
@ViewChildren('slickgrid') slickgrids: QueryList<SlickGrid>;
// tslint:disable-next-line:no-unused-variable
@@ -159,14 +165,20 @@ export class QueryComponent extends GridParentComponent implements OnInit, OnDes
constructor(
@Inject(forwardRef(() => ElementRef)) el: ElementRef,
@Inject(forwardRef(() => ChangeDetectorRef)) cd: ChangeDetectorRef,
@Inject(BOOTSTRAP_SERVICE_ID) bootstrapService: IBootstrapService
@Inject(IInstantiationService) private instantiationService: IInstantiationService,
@Inject(IContextMenuService) contextMenuService: IContextMenuService,
@Inject(IKeybindingService) keybindingService: IKeybindingService,
@Inject(IContextKeyService) contextKeyService: IContextKeyService,
@Inject(IConfigurationService) configurationService: IConfigurationService,
@Inject(IClipboardService) clipboardService: IClipboardService,
@Inject(IQueryEditorService) queryEditorService: IQueryEditorService
) {
super(el, cd, bootstrapService);
super(el, cd, contextMenuService, keybindingService, contextKeyService, configurationService, clipboardService, queryEditorService);
this._el.nativeElement.className = 'slickgridContainer';
this.rowHeight = bootstrapService.configurationService.getValue<any>('resultsGrid').rowHeight;
bootstrapService.configurationService.onDidChangeConfiguration(e => {
this.rowHeight = configurationService.getValue<any>('resultsGrid').rowHeight;
configurationService.onDidChangeConfiguration(e => {
if (e.affectsConfiguration('resultsGrid')) {
this.rowHeight = bootstrapService.configurationService.getValue<any>('resultsGrid').rowHeight;
this.rowHeight = configurationService.getValue<any>('resultsGrid').rowHeight;
this.slickgrids.forEach(i => {
i.rowHeight = this.rowHeight;
});
@@ -182,7 +194,7 @@ export class QueryComponent extends GridParentComponent implements OnInit, OnDes
const self = this;
this.dataService = this.queryParameters.dataService;
this.actionProvider = this._bootstrapService.instantiationService.createInstance(GridActionProvider, this.dataService, this.onGridSelectAll());
this.actionProvider = this.instantiationService.createInstance(GridActionProvider, this.dataService, this.onGridSelectAll());
this.baseInit();
this.setupResizeBind();