Repository: artusjs/core (ts)

Issue:
[RFC] 移除 app.getContainer，规范 Container 获取途径
目前通过 ctx/app 形式获取 Container 的形式是不统一的（`app.getContainer()` / `ctx.container`），希望做出如下统一：

- 对于 ctx/app 上的取值统一为 `container` 属性（即 `ctx.container` / `app.container`）
  - 对于用户的 set 行为（`ctx.container = xxx`）归类为不当使用，后期考虑通过 getter/setter
- 对于经过 IoC 管理的类，统一通过 Inject 完成取值，代码如下：

```ts
// a_singleton_clazz.ts
import { Injectable, Inject, Container } from '@artus/injection';

@Injectable()
export default class MyClazz {
  @Inject()
  container: Container; // Supported by #139 
}

// a_execution_clazz.ts
import { Injectable, Inject, Container, ScopeEnum } from '@artus/injection';

@Injectable({
  scope: ScopeEnum.Execution
})
export default class MyClazz {
  @Inject()
  executionContainer: ExecutionContainer; // Will support
}
```

Pull request:
refactor: remove getContainer
resolve #141 

Patch:
diff --git a/src/application.ts b/src/application.ts
index de6013e..5841420 100644
--- a/src/application.ts
+++ b/src/application.ts
@@ -11,8 +11,8 @@ import { ArtusLogger, Logger } from './logger';
 
 export class ArtusApplication implements Application {
   public manifest?: Manifest;
+  public container: Container;
 
-  protected container: Container;
   protected lifecycleManager: LifecycleManager;
   protected loaderFactory: LoaderFactory;
   protected defaultClazzLoaded = false;
@@ -54,11 +54,6 @@ export class ArtusApplication implements Application {
     return this.container.get(ConfigurationHandler);
   }
 
-  // 兜底方法，不建议对外部使用
-  getContainer(): Container {
-    return this.container;
-  }
-
   async loadDefaultClass() {
     // load Artus default clazz
     this.container.set({ id: ArtusInjectEnum.Application, value: this });
diff --git a/src/trigger/index.ts b/src/trigger/index.ts
index 9ce7499..71d231d 100644
--- a/src/trigger/index.ts
+++ b/src/trigger/index.ts
@@ -22,7 +22,11 @@ export default class Trigger implements TriggerType {
 
   async initContext(input: Input = new Input(), output = new Output()): Promise<Context> {
     const ctx = new Context(input, output);
-    ctx.container = new ExecutionContainer(ctx, this.app.getContainer());
+    ctx.container = new ExecutionContainer(ctx, this.app.container);
+    ctx.container.set({
+      id: ExecutionContainer,
+      value: ctx.container,
+    });
     return ctx;
   }
 
diff --git a/src/types.ts b/src/types.ts
index e612d72..afd40ad 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -17,6 +17,8 @@ export interface ApplicationInitOptions {
 }
 
 export interface Application {
+  container: Container;
+
   manifest?: Manifest;
   config?: Record<string, any>;
 
@@ -25,9 +27,6 @@ export interface Application {
   load(manifest: Manifest): Promise<this>;
   run(): Promise<void>;
   registerHook(hookName: string, hookFn: HookFunction): void;
-
-  // 兜底方法，不建议使用
-  getContainer(): Container;
 }
 
 export interface TriggerType {


Test patch:
diff --git a/test/fixtures/artus_application/src/controller/plugin.ts b/test/fixtures/artus_application/src/controller/plugin.ts
index 39e2c51..5735895 100644
--- a/test/fixtures/artus_application/src/controller/plugin.ts
+++ b/test/fixtures/artus_application/src/controller/plugin.ts
@@ -27,7 +27,7 @@ export default class Hello {
     const app: ArtusApplication = ctx.input.params.app;
     let client;
     try {
-      client = app.getContainer().get('ARTUS_REDIS');
+      client = app.container.get('ARTUS_REDIS');
     } catch {
 
     }
diff --git a/test/fixtures/artus_application/src/index.ts b/test/fixtures/artus_application/src/index.ts
index 20a25eb..49b0aea 100644
--- a/test/fixtures/artus_application/src/index.ts
+++ b/test/fixtures/artus_application/src/index.ts
@@ -13,7 +13,7 @@ export default class MyArtusApplication {
   static async instance(manifest: Manifest): Promise<MyArtusApplication> {
     const app = new ArtusApplication();
     await app.load(manifest, path.join(__dirname, '..'));
-    const instance = app.getContainer().get(MyArtusApplication);
+    const instance = app.container.get(MyArtusApplication);
     return instance;
   }
 
diff --git a/test/fixtures/artus_application/src/plugins/artus_plugin_mysql_ob/src/app.ts b/test/fixtures/artus_application/src/plugins/artus_plugin_mysql_ob/src/app.ts
index 125707f..be128f0 100644
--- a/test/fixtures/artus_application/src/plugins/artus_plugin_mysql_ob/src/app.ts
+++ b/test/fixtures/artus_application/src/plugins/artus_plugin_mysql_ob/src/app.ts
@@ -16,7 +16,7 @@ export default class MyLifecycle implements ApplicationLifecycle {
 
   @LifecycleHook()
   async willReady() {
-    const mysql = this.app.getContainer().get('ARTUS_MYSQL') as Client;
+    const mysql = this.app.container.get('ARTUS_MYSQL') as Client;
     await mysql.init(this.app.config.mysql as MysqlConfig);
   }
 }
diff --git a/test/fixtures/artus_application/src/plugins/artus_plugin_mysql_rds/src/app.ts b/test/fixtures/artus_application/src/plugins/artus_plugin_mysql_rds/src/app.ts
index 125707f..be128f0 100644
--- a/test/fixtures/artus_application/src/plugins/artus_plugin_mysql_rds/src/app.ts
+++ b/test/fixtures/artus_application/src/plugins/artus_plugin_mysql_rds/src/app.ts
@@ -16,7 +16,7 @@ export default class MyLifecycle implements ApplicationLifecycle {
 
   @LifecycleHook()
   async willReady() {
-    const mysql = this.app.getContainer().get('ARTUS_MYSQL') as Client;
+    const mysql = this.app.container.get('ARTUS_MYSQL') as Client;
     await mysql.init(this.app.config.mysql as MysqlConfig);
   }
 }
diff --git a/test/fixtures/artus_application/src/plugins/artus_plugin_redis/src/app.ts b/test/fixtures/artus_application/src/plugins/artus_plugin_redis/src/app.ts
index 352edb0..72f1dba 100644
--- a/test/fixtures/artus_application/src/plugins/artus_plugin_redis/src/app.ts
+++ b/test/fixtures/artus_application/src/plugins/artus_plugin_redis/src/app.ts
@@ -16,7 +16,7 @@ export default class MyLifecycle implements ApplicationLifecycle {
 
   @LifecycleHook()
   async willReady() {
-    const redis = this.app.getContainer().get('ARTUS_REDIS') as Client;
+    const redis = this.app.container.get('ARTUS_REDIS') as Client;
     await redis.init(this.app.config.redis as RedisConfig);
   }
 }
diff --git a/test/loader.test.ts b/test/loader.test.ts
index defd345..c4c801b 100644
--- a/test/loader.test.ts
+++ b/test/loader.test.ts
@@ -63,7 +63,7 @@ describe('test/loader.test.ts', () => {
   describe('custom instance', () => {
     it('should not overide custom instance', async () => {
       const app = await createApp();
-      expect(app.getContainer().get(Custom).getName()).toBe('foo');
+      expect(app.container.get(Custom).getName()).toBe('foo');
     });
   });
 });
diff --git a/test/logger.test.ts b/test/logger.test.ts
index 525cb42..4f1c9af 100644
--- a/test/logger.test.ts
+++ b/test/logger.test.ts
@@ -12,7 +12,7 @@ interface AppConfigWithLoggerOptions extends Record<string, any> {
 const _getAppWithConfig = async (config: AppConfigWithLoggerOptions = {}, manifest: Manifest = { items: [] }) => {
   const app = new ArtusApplication();
   await app.load(manifest);
-  app.getContainer().set({
+  app.container.set({
     id: ArtusInjectEnum.Config,
     value: config,
   });
@@ -107,7 +107,7 @@ describe('test/logger.test.ts', () => {
       const { default: manifest } = await import('./fixtures/logger/src');
       const app = await _getAppWithConfig({}, manifest);
 
-      const testClazz = app.getContainer().get(TestLoggerClazz);
+      const testClazz = app.container.get(TestLoggerClazz);
 
       testClazz.testTrace('trace', 0, {});
       expect(console.trace).toBeCalledTimes(0);
@@ -134,7 +134,7 @@ describe('test/logger.test.ts', () => {
       const { default: manifest } = await import('./fixtures/logger/src');
       const app = await _getAppWithConfig({}, manifest);
 
-      const testClazz = app.getContainer().get(TestLoggerClazz);
+      const testClazz = app.container.get(TestLoggerClazz);
 
       testClazz.testLog(LoggerLevel.TRACE, 'trace', 0, {});
       expect(console.trace).toBeCalledTimes(0);
@@ -250,7 +250,7 @@ describe('test/logger.test.ts', () => {
         },
       }, manifest);
 
-      const testClazz = app.getContainer().get(TestLoggerClazz);
+      const testClazz = app.container.get(TestLoggerClazz);
 
       testClazz.testTrace('trace', 0, {});
       expect(console.trace).toBeCalledTimes(1);
@@ -283,7 +283,7 @@ describe('test/logger.test.ts', () => {
         },
       }, manifest);
 
-      const testClazz = app.getContainer().get(TestLoggerClazz);
+      const testClazz = app.container.get(TestLoggerClazz);
 
       testClazz.testLog(LoggerLevel.TRACE, 'trace', 0, {});
       expect(console.trace).toBeCalledTimes(1);
@@ -327,7 +327,7 @@ describe('test/logger.test.ts', () => {
     it('should log message with custom method', async () => {
       const { manifestWithCustomLogger: manifest } = await import('./fixtures/logger/src');
       const app = await _getAppWithConfig({}, manifest);
-      const testClazz = app.getContainer().get(TestCustomLoggerClazz);
+      const testClazz = app.container.get(TestCustomLoggerClazz);
 
       app.logger.info('info', 0, {});
       expect(console.info).toBeCalledTimes(1);