Categories

Links

在visual basic 6中实现ioc(初稿)


大家可以猜到,主要的手段是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>

[2004-06-30 13:17:02 | Author:jiangjianxiao ] [] 9 comments

Python 在iis

如果你像我一样喜欢python,肯定非常关心python在iis中的运行情况。当然,你可能会像我一样,在对用vbscript,jscript这些对oo支持不是很好的语言使用中遭遇问题时才会考虑使用它。

当前,python 可以以cgi或是active scripting方式在运行在asp中

首先,去 http://www.activestate.com 下载activepython 2.3
运行cgi方式
参考
http://support.microsoft.com/default.aspx?scid=kb%3Ben-us%3B276494

activex scripting 方式
参考 http://www.4guysfromrolla.com/webtech/082201-1.shtml
注:文中所说的pyscript.py 在python23\win32com\AXScript\Client ,在2.3中在lib\site-packages\win32comext\axscript\client\中

关于早期版本的一个隐私问题
Python for Windows Extensions Privacy Concern http://starship.python.net/crew/mhammond/win32/PrivacyProblem.html


在asp中使用python,不可避免的要大量同com 打交道,建议看看此文,以了解com在python中的支持情况
http://www.oreilly.com/catalog/pythonwin32/chapter/ch12.html

python 的性能
python本身的性能并不弱,在字符串测试,对象创建,数字运算中,python都远远超过vbscript

python 在asp中的瓶颈
python com对象的速度明显的落后于vbscript,在调用像ado或是Response之类的asp内置对象时,python明显落后于vbscript好几倍。同样,cpu占用也高于vbscript,但这些显然不是问题
1、python在持续的发展会改进语言本身性能
2、python win32扩展的持续发展也有改进性能的可能性
3、与测试环境密集调用不同,真正的应用程序有适当的间隔,而且,借助于python的动态类型和良好的序列化特性,可以减少与com交互的次数

为什么要用python ?
具体原因我不说了,你深入了解python和vbscript才能比较,我基本了解vbscript的细节,现在我也了解python的大部分细节。python 能解决我现在大部分的问题。
性能的差别可以通过升级硬件来解决,更重要的是python还在发展,而vbscript/vb已经停滞。
在未来一段时间内,我会投入更多的时间到python/ruby/java中去

ruby 在iis -activeruby
http://arton.hp.infoseek.co.jp/
显然ruby 在性能上要超过python,但在调用com时,也落后vbscript 2倍

[2004-02-20 10:21:51 | Author:jiangjianxiao ] [] 1 comments

转换建行网上支付java 接口到.net

建行提供的java 接口在ccb目录中,包括以下一些子目录
au
javax
ccb

其中
au 是一个security provider
javax 实际上是jdk中的内容,我们不用管它,通过引用我们编译的 jce.dll 就可以得到
而ccb\PUB\RSASig.java 则是简化调用的一个类,代码公开
鉴于au部分没有代码,我们使用Visual J# 二进制转换器工具jbimp 进行转换

C:\jce-jdk11-122\ccb>jbimp /recurse c:\ccb\au /t:library /r:c:\jce
-jdk11-122\src\jce.dll

我们得到一个 au.net.aba.crypto.provider.ABAProvider.dll ,让我们需要把它改名为ABAProvider.dll

在项目中引用jce.dll,ABAProvider.dll,导入RSASig.java
下面是测试代码
String SignData;
String HashData;
   HashData="你签名前的数据";
  SignData="你签名后的数据";
RSASig sig=new RSASig();
  sig.setPublicKey("你的public key");
System.out.print(sig.verifySigature(SignData,HashData));

[2004-02-18 15:53:25 | Author:jiangjianxiao ] [] 1 comments

visual j# -编译 BouncyCastle JCE

关于BouncyCastle JCE 请参见csdn中的一系列文章
http://www.csdn.net/Develop/article/23/23830.shtm
http://www.csdn.net/Develop/article/23/23831.shtm
http://www.csdn.net/Develop/article/23/23813.shtm
http://www.csdn.net/develop/article/24/24136.shtm
http://www.csdn.net/develop/article/24/24137.shtm
http://www.csdn.net/develop/article/24/24138.shtm

我们要从首先要从BouncyCastle的网站下载其jdk 1.1版本

展开到一磁盘目录,如c:\jce-jdk11-122

创建一个nant build文件
<project name="jce" default="build">
    <target name="build">
        <vjc target="library" output="jce.dll">
            <sources>
                <includes name="**/*.java"/>
            </sources>
        </vjc>
    </target>
</project>

运行build
有一些警告,主要是java目录中有些类重叠了,不用管它


使用bouncyCastle jce

对于java ,需要在安全属性文件java.security中增加一条
security.provider.x=org.bouncycastle.jce.provider.BouncyCastleProvider
注:x 是你的提供顺序号,你可能有多个提供者

对于visual j#,则需要在
winnt\microsoft.net\framework\你的.net framework 版本\
下创建一个vjsharp.config 文件
注意:第一个packageinfo是我们新增的
<jsharpconfiguration>
     <security>
          <packageinfo>
               <description>This package provides a security provider used in this sample</description>
               <loadinfo class="org.bouncycastle.jce.provider.BouncyCastleProvider,jce, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null, Custom=null">
                    <load/>
               </loadinfo>
          </packageinfo>
   <packageinfo>
               <description>This is the default security provider that ships with Visual J# .NET</description>
               <loadinfo class="com.ms.vjsharp.security.provider.ms, vjslib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A, Custom=null">
                    <load/>
               </loadinfo>
          </packageinfo>
     </security>
</jsharpconfiguration>

接下去你可以在visual j#中运行csdn介绍文档中的一些代码了

推荐书
java 安全 第二版

[2004-02-18 15:51:07 | Author:jiangjianxiao ] [] 3 comments

yukon .net自定义函数实践

自定义函数在sql server2000和yukon分三种
Scalar-Valued Functions 标量函数,返回一个值,如Int32等
Table-Valued Functions  表值函数,返回一个table
inline function 内联函数
这里介绍svf和tvf

对于标量函数必须施于
[SqlFunction (DataAccess = DataAccessKind.Read)]

对于tvf,必须正确设置TableDefinition属性
 

 [SqlFunc (TableDefinition = "customerid int,Customername varchar(50)")]
    public static ISqlReader GetCustomerList ()
    {
        SqlCommand cmd = SqlContext.GetCommand ();
        SqlPipe pipe = SqlContext.GetPipe ();
        cmd.CommandType = CommandType.Text;
        cmd.CommandText = "select Customerid,Customername from customer";


        SqlDataReader reader = cmd.ExecuteReader ();

        CustomerReader c = new CustomerReader (reader);
        return (ISqlReader)c;
    }

ISqlReader 接口实现
对返回table的自定义函数,需要实现ISqlReader,虽然SqlDataReader和SqlResultSet实现了该接口,但好像不能直接传回它(理由可能就是这些是服务端的,在调用结束后被关闭)

服务器: 消息 6257,级别 16,状态 1,行 1
An error occurred while checking metadata of returned ISqlReader for table valued CLR function: System.InvalidOperationException: RecordSet is closed.
 at System.Data.SqlServer.SqlDataReader.get_FieldCount() +61 (native offset)

因此,通常需要创建集合来缓存返回的数据,然后通过一个实现ISqlReader读取和返回这些数据,下面是一个示例
注:这个示例仅仅用于说明如何创建一个返回table value的自定义函数,在实际操作中,这样的操作直接通过t-sql创建会更好些,在实际应用中,往往是需要将需要经过一些运算后的值组织成table返回时才使用.net 方案


完成该任务的t-sql非常简单

Create function GetCustomerList()
 returns @customtable table(customerid int,Customername nvarchar(50))
as
select customerid,customername from customer

过程
Ⅰ创建一个类或结构,用于表示每一条记录
Ⅱ创建一个集合,表示一个table的所有记录
Ⅲ实现Read,GetSqlMetaData,FieldCount和每字段对应的Geter方法


创建一个类
   class Customer
    {
        public int CustomerId;
        public string CustomerName;
    }

实现ISqlReader接口

  public class CustomerReader : ISqlReader
{
//借助泛型,简化一些代码
  private List<Customer> list=new List<Customer>();
//声明position变量,在read实现中使用
private int position=0;

//构造函数
  internal CustomerReader (SqlDataReader reader)
        {
            while (reader.Read ())
            {
                Customer c = new Customer (int.Parse(reader["customerid"].ToString()),reader["customername"].ToString());
                list.Add (c);
               
            }
        }

//实现FieldCount
  int System.Data.Sql.ISqlRecord.FieldCount
        {
            get
            {
                return 2;
            }
        }
//实现GetSqlMetaData
 SqlMetaData System.Data.Sql.ISqlGetTypedData.GetSqlMetaData (int i)
        {
           if (i==0)
               return new SqlMetaData ("CustomerId", SqlDbType.Int);
           return new SqlMetaData ("CustomerName", SqlDbType.VarChar, 50);
        }

//实现read
 bool System.Data.Sql.ISqlReader.Read ()
        {
          if (position==list.Count)
              return false;
          position++;
          return true;
        }


//接下来,要根据列类型的不同,实现相应的Get方法
//这里,我们实现GetSqlChars,当列类型是nvarchar或varchar时
    SqlChars System.Data.Sql.ISqlGetTypedData.GetSqlChars (int i)
        {
            return new SqlChars (list[position - 1].CustomerName);

        }
//GetSqlInt32 当列类型是int时
 SqlInt32 System.Data.Sql.ISqlGetTypedData.GetSqlInt32 (int i)
        {
            return SqlInt32.Parse (list[position-1].CustomerId.ToString());
        }
}

.


 

[2004-01-31 20:22:34 | Author:jiangjianxiao ] [] 1 comments

Total 91 Display 86 of 90
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
Powered by Google App Engine