Repository: artusjs/core (ts)

Issue:
[RFC] 精简 core 对外透出的装饰器
* Injectable 的简单语法糖是否还有必要保留
  * https://github.com/artusjs/core/blob/master/src/logger/decorator.ts#L4

可以保留基类，去除  application 上的引用，上游继承后直接 `Inject` 基类或者实现类来通过 IoC 的标准形式进行引入。

Pull request:
refactor(logger): remove DefineLogger and InjectEnum
resolve #190 

- 移除不必要的覆盖式自定义类逻辑
   - 包括 DefineXXX 装饰器，和 InjectEnum 枚举值
   - 替换为 IoC 管理 / Core 提供 Interface / 上层各自实现的思路
- 与 Trigger 对齐命名格式

主要变更：
- 移除 DefineLogger 装饰器
- 移除 ArtusInjectEnum.Logger 枚举
- 修改 app.logger getter 为获取内置实现
  - 上层框架如有需求需自行 override
- Logger(Interface) 更名为 LoggerType(Interface)
- ArtusLogger(Class) 更名为 Logger(Class)

Patch:
diff --git a/src/application.ts b/src/application.ts
index f1fbe4a..57076fe 100644
--- a/src/application.ts
+++ b/src/application.ts
@@ -7,7 +7,7 @@ import { LoaderFactory, Manifest } from './loader';
 import { Application, ApplicationInitOptions } from './types';
 import Trigger from './trigger';
 import ConfigurationHandler from './configuration';
-import { ArtusLogger, Logger } from './logger';
+import { Logger } from './logger';
 
 export class ArtusApplication implements Application {
   public manifest?: Manifest;
@@ -36,10 +36,6 @@ export class ArtusApplication implements Application {
     return this.container.get(ArtusInjectEnum.Frameworks);
   }
 
-  get logger(): Logger {
-    return this.container.get(ArtusInjectEnum.Logger);
-  }
-
   get packages(): Record<string, any> {
     return this.container.get(ArtusInjectEnum.Packages);
   }
@@ -59,7 +55,7 @@ export class ArtusApplication implements Application {
     this.container.set({ id: ArtusInjectEnum.LifecycleManager, value: this.lifecycleManager });
 
     this.container.set({ type: ConfigurationHandler });
-    this.container.set({ type: ArtusLogger });
+    this.container.set({ type: Logger });
     this.container.set({ type: Trigger });
     this.container.set({ type: ExceptionHandler });
   }
diff --git a/src/constant.ts b/src/constant.ts
index 694b3bc..f701634 100644
--- a/src/constant.ts
+++ b/src/constant.ts
@@ -9,7 +9,6 @@ export enum ArtusInjectEnum {
   DefaultContainerName = 'artus#default_container',
   Frameworks = 'artus#framework-config',
   LifecycleManager = 'artus#lifecycle-manager',
-  Logger = 'artus#logger',
   Packages = 'artus#packages',
 }
 
diff --git a/src/logger/base.ts b/src/logger/base.ts
deleted file mode 100644
index 0cbcb2b..0000000
--- a/src/logger/base.ts
+++ /dev/null
@@ -1,56 +0,0 @@
-import { Container, Inject } from '@artus/injection';
-import { ArtusInjectEnum } from '../constant';
-import { LoggerLevel, LOGGER_LEVEL_MAP } from './level';
-import { Logger, LoggerOptions, LogOptions } from './types';
-
-export class BaseLogger implements Logger {
-
-  @Inject()
-  private container!: Container;
-
-  protected get loggerOpts(): LoggerOptions {
-    let appConfig: Record<string, any> = {};
-    try {
-      appConfig = this.container.get(ArtusInjectEnum.Config);
-    } catch(e) {
-      // do nothing
-    }
-    return appConfig?.logger ?? {};
-  }
-
-  protected checkLoggerLevel(level: LoggerLevel) {
-    const targetLevel = this.loggerOpts.level ?? LoggerLevel.INFO;
-    if (LOGGER_LEVEL_MAP[level] < LOGGER_LEVEL_MAP[targetLevel]) {
-      return false;
-    }
-    return true;
-  }
-
-  trace(_message: string, ..._args: any[]): void {
-    throw new Error('Not implemented');
-  }
-
-  debug(_message: string, ..._args: any[]): void {
-    throw new Error('Not implemented');
-  }
-
-  info(_message: string, ..._args: any[]): void {
-    throw new Error('Not implemented');
-  }
-
-  warn(_message: string, ..._args: any[]): void {
-    throw new Error('Not implemented');
-  }
-
-  error(_message: string|Error, ..._args: any[]): void {
-    throw new Error('Not implemented');
-  }
-
-  fatal(_message: string|Error, ..._args: any[]): void {
-    throw new Error('Not implemented');
-  }
-
-  log(_opts: LogOptions): void {
-    throw new Error('Not implemented');
-  }
-}
diff --git a/src/logger/decorator.ts b/src/logger/decorator.ts
deleted file mode 100644
index 1a32f2b..0000000
--- a/src/logger/decorator.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import { Injectable, InjectableOption, ScopeEnum } from '@artus/injection';
-import { ArtusInjectEnum, SHOULD_OVERWRITE_VALUE } from '../constant';
-
-export const DefineLogger = (injectableOpts: InjectableOption = {}): ClassDecorator => {
-  return (target: any) => {
-    Reflect.defineMetadata(SHOULD_OVERWRITE_VALUE, true, target);
-    return Injectable({
-      id: ArtusInjectEnum.Logger,
-      scope: ScopeEnum.SINGLETON,
-      ...injectableOpts,
-    })(target);
-  };
-};
diff --git a/src/logger/impl.ts b/src/logger/impl.ts
index c10b939..b91241a 100644
--- a/src/logger/impl.ts
+++ b/src/logger/impl.ts
@@ -1,10 +1,33 @@
-import { BaseLogger } from './base';
-import { DefineLogger } from './decorator';
-import { LoggerLevel } from './level';
-import { LogOptions } from './types';
+import { Container, Inject, Injectable, ScopeEnum } from '@artus/injection';
+import { ArtusInjectEnum } from '../constant';
+import { LoggerLevel, LOGGER_LEVEL_MAP } from './level';
+import { LoggerOptions, LoggerType, LogOptions } from './types';
+
+@Injectable({
+  scope: ScopeEnum.SINGLETON,
+})
+export default class Logger implements LoggerType {
+  @Inject()
+  protected container!: Container;
+
+  protected get loggerOpts(): LoggerOptions {
+    let appConfig: Record<string, any> = {};
+    try {
+      appConfig = this.container.get(ArtusInjectEnum.Config);
+    } catch(e) {
+      // do nothing
+    }
+    return appConfig?.logger ?? {};
+  }
+
+  protected checkLoggerLevel(level: LoggerLevel) {
+    const targetLevel = this.loggerOpts.level ?? LoggerLevel.INFO;
+    if (LOGGER_LEVEL_MAP[level] < LOGGER_LEVEL_MAP[targetLevel]) {
+      return false;
+    }
+    return true;
+  }
 
-@DefineLogger()
-export default class ArtusLogger extends BaseLogger {
   public trace(message: string, ...args: any[]) {
     if (!this.checkLoggerLevel(LoggerLevel.TRACE)) {
       return;
diff --git a/src/logger/index.ts b/src/logger/index.ts
index d499a7e..cb1cc85 100644
--- a/src/logger/index.ts
+++ b/src/logger/index.ts
@@ -1,7 +1,5 @@
-import ArtusLogger from './impl';
+import Logger from './impl';
 
-export * from './decorator';
+export { Logger };
 export * from './level';
 export * from './types';
-
-export { ArtusLogger };
diff --git a/src/logger/types.ts b/src/logger/types.ts
index 4286d11..73a03f4 100644
--- a/src/logger/types.ts
+++ b/src/logger/types.ts
@@ -10,7 +10,7 @@ export interface LogOptions {
   splat?: any[];
 }
 
-export interface Logger {
+export interface LoggerType {
   trace(message: string, ...args: any[]): void;
   debug(message: string, ...args: any[]): void;
   info(message: string, ...args: any[]): void;


Test patch:
diff --git a/test/app.test.ts b/test/app.test.ts
index ba71874..c5f39a2 100644
--- a/test/app.test.ts
+++ b/test/app.test.ts
@@ -25,7 +25,6 @@ describe('test/app.test.ts', () => {
         // Check Artus Default Class Inject to Contianer
         expect(() => app.container.get(ArtusInjectEnum.Application)).not.toThrow();
         expect(() => app.container.get(ArtusInjectEnum.LifecycleManager)).not.toThrow();
-        expect(() => app.container.get(ArtusInjectEnum.Logger)).not.toThrow();
         expect(() => app.container.get(ExceptionHandler)).not.toThrow();
         expect(() => app.container.get(ConfigurationHandler)).not.toThrow();
 
diff --git a/test/fixtures/logger/src/custom_logger.ts b/test/fixtures/logger/src/custom_logger.ts
index 8117fe7..07d5f6f 100644
--- a/test/fixtures/logger/src/custom_logger.ts
+++ b/test/fixtures/logger/src/custom_logger.ts
@@ -1,8 +1,9 @@
-import { DefineLogger } from '../../../../src/logger';
-import { BaseLogger } from '../../../../src/logger/base';
+import { Injectable, Logger, ScopeEnum } from '../../../../src';
 
-@DefineLogger()
-export default class CustomLogger extends BaseLogger {
+@Injectable({
+  scope: ScopeEnum.SINGLETON,
+})
+export default class CustomLogger extends Logger {
   public info(message: string, ...args: any[]): void {
     console.info('[Custom]', message, ...args);
   }
diff --git a/test/fixtures/logger/src/test_clazz.ts b/test/fixtures/logger/src/test_clazz.ts
index e96e594..b365da9 100644
--- a/test/fixtures/logger/src/test_clazz.ts
+++ b/test/fixtures/logger/src/test_clazz.ts
@@ -1,12 +1,12 @@
 import { Inject, Injectable, ScopeEnum } from '@artus/injection';
-import { ArtusLogger, LoggerLevel } from '../../../../src/logger';
+import { Logger, LoggerLevel } from '../../../../src/logger';
 
 @Injectable({
   scope: ScopeEnum.SINGLETON,
 })
 export default class TestLoggerClazz {
   @Inject()
-  private logger!: ArtusLogger;
+  private logger!: Logger;
 
   public testLog(level: LoggerLevel, message: string | Error, ...splat: any[]) {
     this.logger.log({
diff --git a/test/fixtures/logger/src/test_custom_clazz.ts b/test/fixtures/logger/src/test_custom_clazz.ts
index 87b4312..e3459b9 100644
--- a/test/fixtures/logger/src/test_custom_clazz.ts
+++ b/test/fixtures/logger/src/test_custom_clazz.ts
@@ -6,7 +6,7 @@ import CustomLogger from './custom_logger';
 })
 export default class TestCustomLoggerClazz {
   @Inject()
-  private logger!: CustomLogger;
+  private logger: CustomLogger;
 
   public testInfo(message: string, ...args: any[]) {
     this.logger.info(message, ...args);
diff --git a/test/logger.test.ts b/test/logger.test.ts
index 4f1c9af..f3bb671 100644
--- a/test/logger.test.ts
+++ b/test/logger.test.ts
@@ -31,78 +31,6 @@ describe('test/logger.test.ts', () => {
   });
 
   describe('log message with default level (INFO)', () => {
-    it('should log message with app.logger', async () => {
-      const app = await _getAppWithConfig();
-
-      app.logger.trace('trace', 0, {});
-      expect(console.trace).toBeCalledTimes(0);
-
-      app.logger.debug('debug', 1, {});
-      expect(console.debug).toBeCalledTimes(0);
-
-      app.logger.info('info', 2, {});
-      expect(console.info).toBeCalledTimes(1);
-      expect(console.info).toBeCalledWith('info', 2, {});
-
-      app.logger.warn('warn', 3, {});
-      expect(console.warn).toBeCalledTimes(1);
-      expect(console.warn).toBeCalledWith('warn', 3, {});
-
-      app.logger.error('error', 4, {});
-      app.logger.error(err, 5, {});
-      expect(console.error).toBeCalledTimes(2);
-      expect(console.error).toBeCalledWith('error', 4, {});
-      expect(console.error).toBeCalledWith(err, 5, {});
-    });
-
-    it('should log message with app.logger and log method', async () => {
-      const app = await _getAppWithConfig();
-
-      app.logger.log({
-        level: LoggerLevel.TRACE,
-        message: 'trace', 
-        splat: [ 0, {} ],
-      });
-      expect(console.trace).toBeCalledTimes(0);
-
-      app.logger.log({
-        level: LoggerLevel.DEBUG,
-        message: 'debug',
-        splat: [ 1, {} ],
-      });
-      expect(console.debug).toBeCalledTimes(0);
-
-      app.logger.log({
-        level: LoggerLevel.INFO,
-        message: 'info',
-        splat: [ 2, {} ],
-      });
-      expect(console.info).toBeCalledTimes(1);
-      expect(console.info).toBeCalledWith('info', 2, {});
-
-      app.logger.log({
-        level: LoggerLevel.WARN,
-        message: 'warn',
-        splat: [ 3, {} ],
-      });
-      expect(console.warn).toBeCalledTimes(1);
-      expect(console.warn).toBeCalledWith('warn', 3, {});
-
-      app.logger.log({
-        level: LoggerLevel.ERROR,
-        message: 'error',
-        splat: [ 4, {} ],
-      });
-      app.logger.log({
-        level: LoggerLevel.ERROR,
-        message: err,
-        splat: [ 5, {} ],
-      });
-      expect(console.error).toBeCalledTimes(2);
-      expect(console.error).toBeCalledWith('error', 4, {});
-      expect(console.error).toBeCalledWith(err, 5, {});
-    });
-
     it('should log message with Logger from Contianer', async () => {
       const { default: manifest } = await import('./fixtures/logger/src');
       const app = await _getAppWithConfig({}, manifest);
@@ -159,89 +87,6 @@ describe('test/logger.test.ts', () => {
   });
 
   describe('log message with custom level (TRACE)', () => {
-    it('should log message with app.logger', async () => {
-      const app = await _getAppWithConfig({
-        logger: {
-          level: LoggerLevel.TRACE,
-        },
-      });
-
-      app.logger.trace('trace', 0, {});
-      expect(console.trace).toBeCalledTimes(1);
-      expect(console.trace).toBeCalledWith('trace', 0, {});
-
-      app.logger.debug('debug', 1, {});
-      expect(console.debug).toBeCalledTimes(1);
-      expect(console.debug).toBeCalledWith('debug', 1, {});
-
-      app.logger.info('info', 2, {});
-      expect(console.info).toBeCalledTimes(1);
-      expect(console.info).toBeCalledWith('info', 2, {});
-
-      app.logger.warn('warn', 3, {});
-      expect(console.warn).toBeCalledTimes(1);
-      expect(console.warn).toBeCalledWith('warn', 3, {});
-
-      app.logger.error('error', 4, {});
-      app.logger.error(err, 5, {});
-      expect(console.error).toBeCalledTimes(2);
-      expect(console.error).toBeCalledWith('error', 4, {});
-      expect(console.error).toBeCalledWith(err, 5, {});
-    });
-    it('should log message with app.logger and log method', async () => {
-      const app = await _getAppWithConfig({
-        logger: {
-          level: LoggerLevel.TRACE,
-        },
-      });
-
-      app.logger.log({
-        level: LoggerLevel.TRACE,
-        message: 'trace', 
-        splat: [ 0, {} ],
-      });
-      expect(console.trace).toBeCalledTimes(1);
-      expect(console.trace).toBeCalledWith('trace', 0, {});
-
-      app.logger.log({
-        level: LoggerLevel.DEBUG,
-        message: 'debug',
-        splat: [ 1, {} ],
-      });
-      expect(console.debug).toBeCalledTimes(1);
-      expect(console.debug).toBeCalledWith('debug', 1, {});
-
-      app.logger.log({
-        level: LoggerLevel.INFO,
-        message: 'info',
-        splat: [ 2, {} ],
-      });
-      expect(console.info).toBeCalledTimes(1);
-      expect(console.info).toBeCalledWith('info', 2, {});
-
-      app.logger.log({
-        level: LoggerLevel.WARN,
-        message: 'warn',
-        splat: [ 3, {} ],
-      });
-      expect(console.warn).toBeCalledTimes(1);
-      expect(console.warn).toBeCalledWith('warn', 3, {});
-
-      app.logger.log({
-        level: LoggerLevel.ERROR,
-        message: 'error',
-        splat: [ 4, {} ],
-      });
-      app.logger.log({
-        level: LoggerLevel.ERROR,
-        message: err,
-        splat: [ 5, {} ],
-      });
-      expect(console.error).toBeCalledTimes(2);
-      expect(console.error).toBeCalledWith('error', 4, {});
-      expect(console.error).toBeCalledWith(err, 5, {});
-    });
-
     it('should log message with Logger from Contianer', async () => {
       const { default: manifest } = await import('./fixtures/logger/src');
       const app = await _getAppWithConfig({
@@ -309,36 +154,15 @@ describe('test/logger.test.ts', () => {
     });
   });
 
-  describe('log message with Error and not-error level', () => {
-    it('should log message with app.logger and log method', async () => {
-      const app = await _getAppWithConfig();
-
-      app.logger.log({
-        level: LoggerLevel.INFO,
-        message: err,
-      });
-
-      expect(console.info).toBeCalledTimes(1);
-      expect(console.info).toBeCalledWith(err.stack);
-    });
-  });
-
   describe('log message with custom Logger', () => {
     it('should log message with custom method', async () => {
       const { manifestWithCustomLogger: manifest } = await import('./fixtures/logger/src');
       const app = await _getAppWithConfig({}, manifest);
       const testClazz = app.container.get(TestCustomLoggerClazz);
 
-      app.logger.info('info', 0, {});
-      expect(console.info).toBeCalledTimes(1);
-      expect(console.info).toBeCalledWith('[Custom]', 'info', 0, {});
-
       testClazz.testInfo('info', 1, {});
-      expect(console.info).toBeCalledTimes(2);
+      expect(console.info).toBeCalledTimes(1);
       expect(console.info).toBeCalledWith('[Custom]', 'info', 1, {});
-
-      expect(() => app.logger.error(err)).toThrow(new Error('Not implemented'));
-      expect(() => testClazz.testError(err)).toThrow(new Error('Not implemented'));
     });
   });
 });