class Container {
private:
std::map> creators;
public:
template
void register_type() {
creators[typeid(T)] = []() -> void* {
return new T();
};
}
template zuojiankuohaophpcntypename Tyoujiankuohaophpcn
std::unique_ptrzuojiankuohaophpcnTyoujiankuohaophpcn resolve() {
auto it = creators.find(typeid(T));
if (it != creators.end()) {
return std::unique_ptrzuojiankuohaophpcnTyoujiankuohaophpcn(static_castzuojiankuohaophpcnT*youjiankuohaophpcn(it-youjiankuohaophpcnsecond()));
}
return nullptr;
}};
这个容器允许你注册类型,并通过resolve获取其实例。比如:
Container container;
container.register_type();
auto db = container.resolve();
db->connect();
面向接口编程与绑定实现
真正的IoC优势体现在“面向接口编程”。C++中可以用抽象基类模拟接口:
class IDbConnection {
public:
virtual ~IdbConnection() = default;
virtual void open() = 0;
};
class MySqlConn : public IDbConnection {
public:
void open() override { / ... / }
};
class MongoConn : public IDbConnection {
public:
void open() override { / ... / }
};
此时容器无法直接注册抽象类型,我们需要扩展容器支持接口到实现的绑定:
template
void register_interface() {
creators[typeid(Interface)] = []() -> void* {
return new Implementation();
};
}
然后这样使用:
container.register_interface();
auto conn = container.resolve();
conn->open(); // 调用实际实现
这样,UserService只需依赖IDbConnection,无需知道具体数据库类型,实现了解耦。
生命周期管理与改进方向
上述容器每次resolve都创建新实例,适用于瞬态(Transient)生命周期。若需支持单例(Singleton),可以加入实例缓存:
std::map> creators;
std::map singletons;
template
void register_singleton() {
creators[typeid(T)] = []() -> void* {
static T instance;
return &instance;
};
}
更高级的容器还可以支持:
- 构造函数参数注入(通过模板参数包展开)
- 属性/方法注入
-
作用域管理(如请求级单例)
- 自动类型推导与递归依赖解析
虽然C++缺乏运行时类型信息(RTTI)的完整支持,但通过模板元编程和工厂模式,依然可以构建出实用的DI机制。
基本上就这些。不复杂但容易忽略的是:DI的核心不是容器本身,而是编码时坚持“依赖抽象,不依赖具体”,配合构造注入,才能真正发挥IoC的价值。