C++ 九陰真經之控制反轉 Ioc

 控制反轉(Inversion of Control,縮寫爲IoC),是面向對象編程中的一種設計原則,可以用來減低計算機代碼之間的耦合度。其中最常見的方式叫做依賴注入(Dependency Injection,簡稱DI),還有一種方式叫“依賴查找”(Dependency Lookup)

    實現代碼:

#include <sstream>
#include <string>
#include <unordered_map>
#include <memory>
#include <functional>
#include "anyval.h"
#include "noncopyable.h"
#include "singleton.h"



class IocContainer : public noncopyable
{
public:
	IocContainer() {}
	~IocContainer() {}

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

		RegisterType(strKey, function);
	}

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

		RegisterType(strKey, function);
	}

	template<class T, typename... Args>
	T* Resolve(const std::string& strKey, Args... args)
	{
		auto iter = m_creatorMap.find(strKey);
		if (m_creatorMap.end() == iter)
		{
			return NULL;
		}

		AnyVar resolver = iter->second;
		std::function<T* (Args...)> function = any_cast<std::function<T* (Args...)>>(resolver);
		return function(args...);
	}

	template<class T, typename... Args>
	std::shared_ptr<T> ResolveShared(const std::string& strKey, Args... args)
	{
		T* tmp = Resolve<T, Args...>(strKey, args...);
		return std::shared_ptr<T>(tmp);
	}

private:
	void RegisterType(const std::string& strKey, AnyVar constructor)
	{
		if (m_creatorMap.end() != m_creatorMap.find(strKey))
		{
			throw std::invalid_argument(strKey + " : this key has already exist!");
		} 
		else
		{
			m_creatorMap.emplace(strKey, constructor);
		}
	}

private:
	std::unordered_map<std::string, AnyVar> m_creatorMap;
};



typedef Singleton<IocContainer> IocContainerAgent;

測試代碼:
 

class TestBase
{
public:
    virtual  void show() = 0;
};

class TestIoc : public TestBase
{
public:
    TestIoc(int a, const std::string& msg)
    {

    }
    void show()
    {
        std::cout << "this is TestIoc" << std::endl;
    }
};

int main()
{
    IocContainerAgent::get_instance().RegisterType<TestBase, TestIoc, int, std::string>("testIoc");

    TestBase* pTest = IocContainerAgent::get_instance().Resolve<TestBase>("testIoc", 10, std::string("msg"));
    pTest->show();
    return 1;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章