大家可以猜到,主要的手段是CreateObject和CallByName。在api表现上仿spring framework (http://www.springframework.org),另外,借助了type library v2的一些功能来达成一些复杂的功能
这里不会介绍什么是 ioc,大家可以自行去google查找 在第一个阶段,主要实现的依赖注入,在第二个阶段,则是实现aop功能。依赖注入现在有三种类型
接口 接口实际上是自己去查找,在我们的框架中,实际上是通过实现ApplicationContextAware接口来实现的 ApplicationContextAware只有一个只写属性,就是ApplicationContext
AService.cls
Implements ApplicationContextAware
Private dao As IDao
Public Sub SomeMethod() dao.Create dao.FindById (0) End Sub
Private Property Set ApplicationContextAware_ApplicationContext(RHS As Spring.ApplicationContext) Set dao = RHS.GetBean("daoImpl") End Property
setter
当前问题 Ⅰ在vb6中,实际上在外部无法访问私有或friend等变量 Ⅱ接口实现是显式的,意味着一定要强制转换后才能实现,如果在.net中实现显示实现接口,会遇到同样的问题 以上指出,实际上我们无法对接口的属性进行赋值,举例说,像 IPerson.cls
public property let Name (byval v as string) end property
Person.cls
implements IPerson
private mName as string public property let IPerson_name(byval v as string) mName=v end property
而后想通过 <bean id="person" class="Person"> <property name="Name"><value>jjx</value></property> </bean>
这样是行不同的
构造函数
问题 vb6 可以说是没有构造函数,虽然你可以把class_initialize和Class_Terminate看成构造函数,但它实际上无法发挥构造函数的作用 但是我们还是可以来这样了实现
<bean id="impl" class="SpringTest.AInterfaceImpl" constructor-method="init" singleton="false"> <constructor-arg><ref bean="daoImpl"/></constructor-arg> <constructor-arg><ref bean="person2"/></constructor-arg> <property name="contact"><null/></property> </bean>
源代码
Set obj = VBA.CreateObject(node.Attributes.getNamedItem("class").Text) Dim aware As ApplicationContextAware If TypeOf obj Is ApplicationContextAware Then Set aware = obj Set aware.ApplicationContext = Me End If If LenB(constructor_method) <> 0 Then Call executeConstructor(obj, constructor_method, node) End If
由于对象实例是容器管理的,所以能基本上能达到相同的效果,这是个非常有意思的功能 Private Function executeConstructor(ByRef obj As Object, ByVal constructor_method As String, ByRef node As MSXML2.IXMLDOMNode) Dim nl As MSXML2.IXMLDOMNodeList, currNode As MSXML2.IXMLDOMNode Set nl = node.selectNodes("constructor-arg") Dim v As Variant Dim Col As New Collection Dim i As Long For i = 0 To nl.length - 1 Set currNode = nl(i).childNodes(0) If Not currNode Is Nothing Then Col.Add ProcessNode(currNode) End If Next InvokeMethod obj, constructor_method, ToArray(Col)
End Function
属性值
可以是一个原始类型,如数字,字符串等 <property name="propertyname"><value>1</value></property> 或是null值 <property name="propertyname"><null/></property>
也可以引用一个对象 <property name="propertyname"><ref bean="objContact"/></property>
可以是一个props,有多个prop组成,对应一个key和一个文本值
<property name="propertyname"> <props> <prop key="a">a</prop> <prop key="b">b</prop> </props> </property>
在内部,我们用Dictionary 表示
可以是一个List,在内部,我们用Collection 表示 <property name="propertyname"> <list> <value/> <ref bean="xx"/> <null/> <props/> <list/> <map> </list> </property> 在list内部,可以使用0个或多个value,ref,null,props,list,map
最后是map ,我们内部用Dictionary 表示
<property name="propertyname"> <map> <entry key="xx"> </entry> </property>
entry内部可以使用value,ref,null,props,list,map等
分级的应用程序上下文
在一个复杂的应用中,有多个应用程序上下文在运行,比方说多个配置文件,他们之间建立一个级别,现在支持这种分级 对于GetBean,IsSingleTon,ContansBean这些功能而言,如果在当前应用上下文中没有发现,则将上浮到上级上下文中查找
例子 <?xml version="1.0" encoding="GB2312" ?> <beans> <bean id="person2" class="SpringTest.Person" singleton="false"> <property name="name"><value>jjx</value></property> </bean> <bean id="person3" class="SpringTest.Person" singleton="false"> <property name="name"><value>jxb</value></property> </bean>
<bean id="person" class="SpringTest.Person"> <property name="map"> <map> <entry key="vb"><value>msvb</value></entry> <entry key="vc"><value>msvc</value></entry> <entry key="map"> <map> <entry key="vb"><value>msvb</value></entry> <entry key="vc"><value>msvc</value></entry>
</map> </entry> <entry key="props"> <props> <prop key="a">a</prop> <prop key="b">b</prop> </props>
</entry> <entry key="nullvalue"><null/></entry> <entry key="person"><ref bean="person2"/></entry> </map> </property> <property name="list"> <list> <ref bean="person2"/> <ref bean="person3"/> <props> <prop key="a">a</prop> <prop key="b">b</prop> </props> <map> <entry key="vb"><value>msvb</value></entry> <entry key="vc"><value>msvc</value></entry> <entry key="map"> <map> <entry key="vb"><value>msvb</value></entry> <entry key="vc"><value>msvc</value></entry>
</map> </entry> <entry key="props"> <props> <prop key="a">a</prop> <prop key="b">b</prop> </props>
</entry> <entry key="nullvalue"><null/></entry> <entry key="person"><ref bean="person2"/></entry> </map>
</list> </property> <property name="address"><value>zj</value></property> <property name="props"> <props> <prop key="e">this is e</prop> <prop key="f">this is f</prop> </props> </property> </bean>
<bean id="contact" class="SpringTest.Contact" singleton="false"> <property name="firstName"><value>jiang</value></property> <property name="lastName"><value>jianxiao</value></property>
</bean> <bean id="daoImpl" class="SpringTest.DaoImpl"/> <bean id="impl" class="SpringTest.AInterfaceImpl" constructor-method="init" singleton="false"> <constructor-arg><ref bean="daoImpl"/></constructor-arg> <constructor-arg><ref bean="person2"/></constructor-arg> <property name="contact"><null/></property> </bean> <bean id="myService" class="SpringTest.AService"/> </beans> |