使用Autumn框架进行C++依赖注入示例
Posted sunny_ss12
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用Autumn框架进行C++依赖注入示例相关的知识,希望对你有一定的参考价值。
项目中用到了Autumn,看到了一篇简介的文章,记录在这。
转载自:http://blog.csdn.net/logsharp/article/details/1726024 《无他,唯程序尔》该博主好像就是Autumn的作者
1.1. Autumn简介
Autumn Framework是一个C++的依赖注入(DI)框架,它的功能是模仿JAVA领域中的Spring框架来的。当前只是提供依赖注入功能,而且尽量做到对原代码的不侵入。因为C++没有象JAVA那样的动态反射机制,不能很容易地在运行时得到注入的一些相关信息,所以在使用Autumn的时候,需要做一些工作来让Autumn框架知道注入时所需要的一些信息,即使用Autumn自带的一个工具AutumnGen来生成一些Wrapper文件。
通过使用Autumn,可以将动态库很容易地跟原来的程序部署在一起,而不需要重新编译原有程序。
Autumn可以从这儿下载并编译,当前最新版本是0.5.0。
1.2. Autumn示例
例子很简单。文件Action.h中定义了一个接口Action,如下:
class Action
public:
virtual string excute(const char* s) = 0;
;
对该接口做一些不同的实现,然后在我们的程序中调用。
1.2.1. 不使用Autumn的开发过程
我们在文件LowerAction.h中对接口做一个实现LowerAction(因为比较简单,所以没有写.cpp文件),如下:
class LowerAction: public Action
private:
string Message;
public:
LowerAction(const char* msg)
this->Message = msg;
string excute(const char* s)
string r = this->Message + ", " + s;
for( int i = 0; i < r.length(); i++)
r[i] = tolower(r[i]);
return r;
;
在文件UpperAction.h中对接口做另一个新的实现UpperAction,如下:
class UpperAction: public Action
private:
string Message;
public:
void setMessage(const char* msg)
this->Message = msg;
string excute(const char* s)
string r = this->Message + ", " + s;
for( int i = 0; i < r.length(); i++)
r[i] = toupper(r[i]);
return r;
;
现在写主程序。
开始我们想调用LowerAction这个实现:
#include <iostream>
#include "Action.h"
#include "LowerAction.h"
int main(int argc, char* argv[])
Action* pa = new LowerAction(“Hello”);
cout<<pa->excute("Vincent")<<endl;
delete pa ;
return 0;
在主程序中,为LowerAction传入构造参数。编译主程序后,可得到运行结果:
hello, vincent
后来,我们想调用UpperAction这个实现,我们需要修改主程序,如下:
#include <iostream>
#include "Action.h"
#include "UpperAction.h"
int main(int argc, char* argv[])
UpperAction* pua = new UpperAction();
pua->setMessage("Hello");
Action* pa = pua;
cout<<pa->excute("Vincent")<<endl;
delete pa;
return 0;
在主程序中需要为UpperAction的实例设置属性Message。编译主程序后,可得到运行结果:
HELLO, VINCENT
当想换用不同的实现时,我们需要做以下几项工作:
w 修改主程序(原来是要new一个LowerAction,后来要new一个UpperAction);
w 为不同的实现进行实例化相关的一些操作,比如设置属性;
w 重新编译程序。
1.2.2. 使用Autumn的开发过程
Autumn框架尽量做到对原来代码不侵入,所以,使用Autumn框架时,接口文件Action.h及实现文件LowerAction.h和UpperAction.h都不需要修改。使用Autumn开发,大概有如下五个步骤。
1.2.2.1. 生成Wrapper文件
为那些需要Autumn来操作的类(主要是那些用来注入或被注入的类)生成Wrapper。使用AutumnGen可以根据C++的头文件自动生成相关的Wrapper文件。在本示例中为LowerAction和UpperAction生成Wrapper,命令如下:
AutumnGen LowerAction.h UpperAction.h
执行后生成四个文件:LowerAction_Wrapper.h、LowerAction_Wrapper.cpp、UpperAction_Wrapper.h、UpperAction_Wrapper.cpp。
1.2.2.2. 生成动态库
Autumn主要是基于动态库来实现灵活的依赖注入的。我们要把需要Autumn来操作的类及其Wrapper编译到一个动态库中。在本示例中,我们将实现LowerAction、UpperAction及其Wrapper都编译到一个动态库ActionImpl.dll中。
1.2.2.3. 编写配置文件
实现类都存在于ActionImpl.dll中,我们想让其提供LowerAction的实现,可以编写如下一个配置文件autumnDemo.xml:
<?xml version="1.0" encoding="UTF-8"?>
<autumn>
<library path="../lib/ActionImpl.dll" name="ActionImpl">
<beans>
<bean class="LowerAction" name="TheAction">
<constructor-arg>
<argument>
<value>Hello</value>
</argument>
</constructor-arg>
</bean>
</beans>
</library>
</autumn>
Autumn的配置文件采用XML格式,相应的schema文件autumn.xsd在源码包中。本配置文件中指出了动态库的路径(../lib/ActionImpl.dll),实现类的类名(LowerAction),实现类在Autumn中的命名(TheAction),实现类的构造参数(”Hello”)等内容。
1.2.2.4. 编写主程序
主程序中使用Autumn的BeanFactory来取得想使用的实现类,调用其excute方法。程序如下:
#include <iostream>
#include <exception>
#include "Action.h"
#include "IBeanFactory.h"
using namespace std;
int main(int argc, char* argv[])
try
Autumn::IBeanFactory* bf;
bf = Autumn::getBeanFactoryWithXML("autumnDemo.xml");
Action* pa = (Action*)bf->getBean("TheAction");
cout<<pa->excute("Vincent")<<endl;
bf->freeBean(pa);
Autumn::deleteBeanFactory(bf);
catch (const exception& e )
cout<<"Exception: "<<e.what()<<endl;
return 0;
主程序中首先取得BeanFactory,然后调用其getBean方法来取得实现类,用完之后,通过其freeBean来释放该实现类,程序最后释放BeanFactory。Autumn框架中的接口都在名字空间Autumn中。程序编译时需要连接Autumn框架的库文件AutumnFramework.lib(在非Windows平台上是libAutumn.so)。
按照上面1.2.2.3. 中的配置文件,使用的实现类是LowerAction,运行主程序,结果如下:
hello, vincent
1.2.2.5. 换用不同的实现
如果想不用LowerAction,而去使用UpperAction这个实现,可以修改配置文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<autumn>
<library path="../lib/ActionImpl.dll" name="ActionImpl">
<beans>
<bean class="UpperAction" name="TheAction">
<properties>
<property name="Message" type="char*">
<value>Hello</value>
</property>
</properties>
</bean>
</beans>
</library>
</autumn>
保存配置文件后,不需要重新编译任何程序,直接运行主程序,结果如下:
HELLO, VINCENT
如果想更改实现类的属性值,也不需要修改程序,只需要修改Autumn的配置文件即可。修改LowerAction的属性值,只要修改配置文件中的构造参数即可,如把Hello改为Hi;同样如果想修改UpperAction的属性值,只要修改配置文件中它的名字为Message的属性的值即可。
从这儿下载示例源代码。
以上是关于使用Autumn框架进行C++依赖注入示例的主要内容,如果未能解决你的问题,请参考以下文章