首页 > 编程语言 > 详细

C++11写IoC框架

时间:2020-10-31 23:57:31      阅读:58      评论:0      收藏:0      [点我收藏+]

author: lunar
date: Sat 31 Oct 2020 09:18:11 PM CST
location: Shanghai

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;
}

C++11写IoC框架

原文:https://www.cnblogs.com/lunar-ubuntu/p/13907568.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!