C++11写IoC框架

C++11写IoC框架

/**********************************************
  > File Name		: ioc.cpp
  > Author		    : lunar
  > Email			: lunar_ubuntu@qq.com
  > Created Time	: Sat 24 Oct 2020 09:40:40 PM CST
  > Location        : Shanghai
 **********************************************/
#include <unordered_map>
#include <functional>
#include <string>
#include <stdexcept>
#include "any.hpp"
#include <memory>
using namespace std;


//write an IoC framwork with C++11
/*
 * 这个IoC容器可以创建所有类型的接口对象和普通的对象
 */
struct IoCContainer {
    IoCContainer(void) {}
    ~IoCContainer(void) {}

    //注入继承了同一接口的类型
    //T表示包含了接口类的一个类型
    //下面两个通过enable_if进行RegisterType的重载是老套路了
    template <typename T, typename Depend, typename... Args>
    typename std::enable_if<!std::is_base_of<T, Depend>::value>::type RegisterType(const string& className) {
        std::function<T*(Args...)> function = [](Args... args){return new T(new Depend(args...));};
        RegisterType(className, function);
    }

    template <typename T, typename Depend, typename... Args>
    typename std::enable_if<std::is_base_of<T, Depend>::value>::type RegisterType(const string& className) {
        std::function<T*(Args...)> function = [](Args... args){return new Depend(args...);};
        RegisterType(className, function);
    }

    template <typename T, typename... Args>
    void RegisterType(const string& className) {
        std::function<T*(Args...)> function = [](Args... args){return new T(args...);};
        RegisterType(className, function);
    }

    template <class T, typename... Args>
    T* Resolve(const string& className, Args... args) {
        auto it = m_creatorMap.find(className);
        if (it == m_creatorMap.end()) {
            return nullptr;
        }
        Any resolver = it->second;
        std::function<T*(Args...)> function = resolver.AnyCast<std::function<T*(Args...)>>();
        return function(args...);
    }

    //与Resolve作用类似,但是返回值通过shared_ptr包裹,符合RAII原则
    template <class T, typename... Args>
    std::shared_ptr<T> ResolveShared(const string& className, Args... args) {
        T* t = Resolve<T>(className, args...);
        return std::shared_ptr<T>(t);
    }

private:
    void RegisterType(const string& className, Any constructor) {
        if (m_creatorMap.find(className) != m_creatorMap.end()) {
            std::cout << "This class already exists" << std::endl;
            return ;
        }
        m_creatorMap.emplace(className, constructor);
    }

    unordered_map<string, Any> m_creatorMap;
};

struct Bus {
    void test() const {
        cout << "Bus::test()" << endl;
    }
};

struct Car {
    void test() const {
        cout << "Car::test()" << endl;
    }
};

struct Base {
    virtual void func() {}
    virtual ~Base() {}
};

struct DerivedB: Base {
    void func() override {
        cout << "call DerivedB::func()" << endl;
    }
};

struct DerivedC: Base {
    void func() override {
        cout << "call DerivedC::func()" << endl;
    }
};

// 通过A的闭包来擦除类型
struct A {
    A(Base* ptr): m_ptr(ptr) {}
    void func() {
        m_ptr->func();
    }

    ~A() {
        if (m_ptr != nullptr) {
            delete m_ptr;
            m_ptr = nullptr;
        }
    }

private:
    Base* m_ptr;
};

int main() {
    // 测试IoCContainer
    IoCContainer ioc;
    // 配置依赖关系
    ioc.RegisterType<A, DerivedB>("B");
    auto pB = ioc.ResolveShared<A>("B");
    pB->func();
    return 0;
}

posted @   kaleidopink  阅读(487)  评论(0编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示