eclipse-theia / theia

Eclipse Theia is a cloud & desktop IDE framework implemented in TypeScript.
http://theia-ide.org
Eclipse Public License 2.0
19.99k stars 2.5k forks source link

Simplify dependency injection configuration #9639

Open muxiangqiu opened 3 years ago

muxiangqiu commented 3 years ago

Theia is a project with excellent architecture, such as extensions, IoC, dynamic module assembly, front-end integration, and so on. A lot of inspiration for the Serverless First application development framework Malagu I designed comes from Theia. Malagu made further innovations in some of Theia's ideas. For example, drawing on the design of Spring, dependency injection has been greatly simplified. As follows:

import { SessionManager, Session, SessionStrategy, SessionStore, COOKIE_EXP_DATE } from './session-protocol';
import { Autowired, Value, Component } from '@malagu/core';
import { Context } from '../context';

@Component(SessionManager)
export class SessionManagerImpl implements SessionManager {

    @Value('malagu.session.sessionIdKey')
    protected readonly sessionIdKey: string;

    @Value('malagu.session')
    protected readonly sessionOptions: any;

    @Autowired(SessionStrategy)
    protected readonly sessionStrategy: SessionStrategy;

    @Autowired(SessionStore)
    protected readonly sessionStore: SessionStore;

    protected async getSessionId() {
        const cookies = Context.getCookies();
        return cookies.get(this.sessionIdKey);
    }

    async get(): Promise<Session> {
        if (Context.getSession()) {
            return Context.getSession();
        }
        const sessionId = await this.getSessionId();
        if (sessionId) {
            const session = await this.sessionStore.get(sessionId);
            if (session && await this.sessionStrategy.valid(session)) {
                return session;
            }
        }
        return this.sessionStrategy.create();
    }

    async remove(): Promise<void> {
        if (Context.getSession()) {
            await this.sessionStore.remove(Context.getSession().id);
        }
        Context.getCookies().set(this.sessionIdKey, '', {
            expires: COOKIE_EXP_DATE,
            maxAge: false,
        });
    }

    async commit(): Promise<void> {
        const session = Context.getSession();
        if (!session) {
            return;
        }
        if (await this.sessionStrategy.shouldSaveSession(session)) {
            await this.sessionStore.set(session);
            Context.getCookies().set(this.sessionIdKey, session.id, this.sessionOptions);
        }
    }

}

Just import the module that needs to be injected in the module entry file, the code is as follows:

import { autoBind } from '@malagu/core';
import '.';

export default autoBind();

If you need to rebind the default implementation, the code is as follows:

import { DefaultRegionProvider } from '@malagu/cloud/lib/node';
import { Component } from '@malagu/core';
import { RegionProvider } from '@malagu/cloud';

@Component({ id: RegionProvider, rebind: true })
export class FaaSRegionProvider extends DefaultRegionProvider {

    async provide(): Promise<string | undefined> {
        const region = await super.provide();
        if (region) {
            return region;
        }
        return process.env.MALAGU_REGION;
    }
}

Based on Malagu + Theia, I also made another open source project Cellbang, the demo address is as follows: https://cloud.cellbang.com/.

I wonder if Theia can support similar dependency injection configuration simplification?

vince-fugnitto commented 3 years ago

@muxiangqiu unfortunately I'm not sure about updating the way dependency injection works in the system for a couple of reasons:

For these reasons I do not believe moving away from inversify is necessary, or should be a high priority.

muxiangqiu commented 3 years ago

@vince-fugnitto Thank you for your prompt reply.

The new writing method and Theia's existing writing method are compatible with each other and can coexist. However, it is not a high priority and must be done.