### 使用c++11开发一个轻量级的Ioc容器 Ioc容器具备两种能力,一种是对象工厂,不仅可以创建所有的对象,还可以根据配置去创建对象;另一种能力是可以去创建依赖对象,应有不需要直接创建对象,由Ioc容器去创建,实现控制反转。
实现Ioc容器需要解决三个问题,第一个问题是创建所有类型的对象,第二个问题是类型擦除,第三个问题是如何创建依赖对象。 #### 类型擦除的常用方法 类型擦除就是讲原有类型消除或者隐藏。常用的方法有: 1. 通过多态来擦除类型 2. 通过模板来擦除类型 3. 通过某种类型的模板容器擦除类型(Variant) 4. 通过某种通用类型来擦除类型(any) 5. 通过闭包来擦除类型(通过模板函数,将数值包入函数中,再包入std::function) ``` #pragma once #include #include #include #include using namespace std; #include #include class IocContainer : NonCopyable { public: IocContainer(void){} ~IocContainer(void){} template void RegisterType(const string& strKey) { std::function function = [](Args... args){ return new T(new Depend(args...)); };//通过闭包擦除了参数类型 RegisterType(strKey, function); } template T* Resolve(const string& strKey, Args... args) { if (m_creatorMap.find(strKey) == m_creatorMap.end()) returnnullptr; Any resolver = m_creatorMap[strKey]; std::function function = resolver.AnyCast>(); return function(args...); } template std::shared_ptr ResolveShared(const string& strKey, Args... args) { T* t = Resolve(strKey, args...); return std::shared_ptr(t); } private: void RegisterType(const string& strKey, Any constructor) { if (m_creatorMap.find(strKey) != m_creatorMap.end()) throw std::invalid_argument("this key has already exist!"); //通过Any擦除了不同类型的构造器 m_creatorMap.emplace(strKey, constructor); } private: unordered_map m_creatorMap; }; /*test code struct Base { virtual void Func(){} virtual ~Base(){} }; struct DerivedB : public Base { DerivedB(int a, double b):m_a(a),m_b(b) { } void Func()override { cout<Func(); } ~A() { if(m_ptr!=nullptr) { delete m_ptr; m_ptr = nullptr; } } private: Base * m_ptr; }; void TestIoc() { IocContainer ioc; ioc.RegisterType(“C”); //配置依赖关系 auto c = ioc.ResolveShared(“C”); ioc.RegisterType(“C”); //注册时要注意DerivedB的参数int和double auto b = ioc.ResolveShared(“C”, 1, 2.0); //还要传入参数 b->Func(); } */ ```