Skip to content

Commit

Permalink
GLSP-1166 Fix dependency injection cycle in selection service (#305)
Browse files Browse the repository at this point in the history
Avoid binding of SelectionService as `IModelRootListner`. Instead directly inject the`CommandStack` into `SelectionService`
and manually register itself as `IGModelRootListener`.
This avoids a circular dependency injection if any of the `SelectionListner`s wants to inject the `ActionDispatcher`.

Fixes eclipse-glsp/glsp/issues/1166
  • Loading branch information
tortmayr authored Nov 29, 2023
1 parent c6dcedd commit 2247067
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 3 deletions.
1 change: 0 additions & 1 deletion packages/client/src/base/default.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,6 @@ export const defaultModule = new FeatureModule((bind, unbind, isBound, rebind, .
bindOrRebind(context, TYPES.ViewRegistry).to(GViewRegistry).inSingletonScope();

bind(SelectionService).toSelf().inSingletonScope();
bind(TYPES.IGModelRootListener).toService(SelectionService);

// Feedback Support ------------------------------------
// Generic re-usable feedback modifying css classes
Expand Down
11 changes: 9 additions & 2 deletions packages/client/src/base/selection-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import {
} from '@eclipse-glsp/sprotty';
import { inject, injectable, multiInject, optional, postConstruct, preDestroy } from 'inversify';
import { getElements, getMatchingElements } from '../utils/gmodel-util';
import { IGModelRootListener } from './command-stack';
import { GLSPCommandStack, IGModelRootListener } from './command-stack';
import { IFeedbackActionDispatcher } from './feedback/feedback-action-dispatcher';

export interface ISelectionListener {
Expand All @@ -61,6 +61,9 @@ export class SelectionService implements IGModelRootListener, Disposable {
@inject(TYPES.ILogger)
protected logger: ILogger;

@inject(TYPES.ICommandStack)
protected commandStack: GLSPCommandStack;

@multiInject(TYPES.ISelectionListener)
@optional()
protected selectionListeners: ISelectionListener[] = [];
Expand All @@ -69,7 +72,11 @@ export class SelectionService implements IGModelRootListener, Disposable {

@postConstruct()
protected initialize(): void {
this.toDispose.push(this.onSelectionChangedEmitter);
this.toDispose.push(
this.onSelectionChangedEmitter,
this.commandStack.onModelRootChanged(root => this.modelRootChanged(root))
);

this.selectionListeners.forEach(listener =>
this.onSelectionChanged(change => listener.selectionChanged(change.root, change.selectedElements, change.deselectedElements))
);
Expand Down

0 comments on commit 2247067

Please sign in to comment.