什么是依赖注入
#依赖注入(Dependency Injection, DI)是一种设计模式,通过外部传入依赖而不是内部创建,实现组件解耦。
为什么使用 DI
#紧耦合的问题
#1
2
3
4
5
6
| // 紧耦合 - 难以测试和替换
class ChatService {
constructor() {
this.model = new GPT4Model(); // 硬编码依赖
}
}
|
解耦后的好处
#1
2
3
4
5
6
| // 松耦合 - 灵活可测试
class ChatService {
constructor(modelProvider) {
this.model = modelProvider; // 外部注入
}
}
|
OpenClaw 中的 DI 实现
#服务容器
# 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| class Container {
constructor() {
this.services = new Map();
}
register(name, factory) {
this.services.set(name, factory);
}
resolve(name) {
const factory = this.services.get(name);
return factory(this);
}
}
// 注册服务
container.register('model', (c) => new OpenAIProvider());
container.register('memory', (c) => new RedisMemory());
container.register('session', (c) =>
new SessionManager(c.resolve('model'), c.resolve('memory'))
);
|
构造函数注入
# 1
2
3
4
5
6
7
8
9
10
11
12
| class SkillExecutor {
constructor(modelProvider, memoryStore, logger) {
this.model = modelProvider;
this.memory = memoryStore;
this.logger = logger;
}
async execute(skill, input) {
this.logger.info(`Executing ${skill.name}`);
// 使用注入的依赖
}
}
|
测试优势
# 1
2
3
4
5
6
7
8
9
10
11
12
13
14
| // 使用 Mock 对象测试
test('skill execution', async () => {
const mockModel = { complete: jest.fn() };
const mockMemory = { get: jest.fn() };
const mockLogger = { info: jest.fn() };
const executor = new SkillExecutor(
mockModel, mockMemory, mockLogger
);
await executor.execute(skill, input);
expect(mockModel.complete).toHaveBeenCalled();
});
|
依赖注入让代码更灵活、更可测试,是构建高质量 OpenClaw 应用的关键技术。