Created
October 9, 2012 12:03
-
-
Save wangye/3858372 to your computer and use it in GitHub Desktop.
ASP/VBScript Dynamic Object Generator ASP/VBScript动态创建属性对象的工厂类
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
' | |
' ASP/VBScript Dynamic Object Generator | |
' Author: WangYe | |
' For more information please visit | |
' http://wangye.org/ | |
' This code is distributed under the BSD license | |
' | |
' UPDATE: | |
' 2012/11/7 | |
' 1. Add variable key validator. | |
' 2. Add hasattr_ property for determine | |
' if the property exists. | |
' 3. Add getattr_ property for get property | |
' value safety. | |
' 4. Class name can be accessed by ClassName_ property. | |
' 5. Fixed some issues. | |
' | |
Const PROPERTY_ACCESS_READONLY = 1 | |
Const PROPERTY_ACCESS_WRITEONLY = -1 | |
Const PROPERTY_ACCESS_ALL = 0 | |
Class DynamicObject | |
Private m_objProperties | |
Private m_strName | |
Private m_objRegExp | |
Private Sub Class_Initialize() | |
Set m_objProperties = CreateObject("Scripting.Dictionary") | |
Set m_objRegExp = New RegExp | |
m_objRegExp.IgnoreCase = True | |
m_objRegExp.Global = False | |
m_objRegExp.Pattern = "^[a-z][a-z0-9]*$" | |
m_strName = "AnonymousObject" | |
m_objProperties.Add "ClassName_", _ | |
Array(m_strName, PROPERTY_ACCESS_READONLY) | |
End Sub | |
Private Sub Class_Terminate() | |
Set m_objRegExp = Nothing | |
If IsObject(m_objProperties) Then | |
m_objProperties.RemoveAll | |
End If | |
Set m_objProperties = Nothing | |
End Sub | |
Public Sub setClassName(strName) | |
If Not m_objRegExp.Test(strName) Then | |
' Skipped Invalid Class Name | |
' Raise | |
Exit Sub | |
End If | |
m_strName = strName | |
m_objProperties("ClassName_") = _ | |
Array(m_strName, PROPERTY_ACCESS_READONLY) | |
End Sub | |
Public Sub add(key, value, access) | |
If Not m_objRegExp.Test(key) Then | |
' Skipped Invalid key | |
' Raise | |
Exit Sub | |
End If | |
If key = "hasattr_" Then key = "hasattr__" | |
If key = "ClassName_" Then key = "ClassName__" | |
'Response.Write key | |
m_objProperties.Add key, Array(value, access) | |
End Sub | |
Public Sub setValue(key, value, access) | |
If m_objProperties.Exists(key) Then | |
m_objProperties.Item(key)(0) = value | |
m_objProperties.Item(key)(1) = access | |
Else | |
add key,value,access | |
End If | |
End Sub | |
Private Function getReadOnlyCode(strKey) | |
Dim strPrivateName, strPublicGetName | |
strPrivateName = "m_var" & strKey | |
strPublicGetName = "get" & strKey | |
getReadOnlyCode = _ | |
"Public Function " & strPublicGetName & "() :" & _ | |
strPublicGetName & "=" & strPrivateName & " : " & _ | |
"End Function : Public Property Get " & strKey & _ | |
" : " & strKey & "=" & strPrivateName & _ | |
" : End Property : " | |
End Function | |
Private Function getWriteOnlyCode(strKey) | |
Dim pstr | |
Dim strPrivateName, strPublicSetName, strParamName | |
strPrivateName = "m_var" & strKey | |
strPublicSetName = "set" & strKey | |
strParamName = "param" & strKey | |
getWriteOnlyCode = _ | |
"Public Sub " & strPublicSetName & _ | |
"(" & strParamName & ") :" & _ | |
strPrivateName & "=" & strParamName & " : " & _ | |
"End Sub : Public Property Let " & strKey & _ | |
"(" & strParamName & ")" & _ | |
" : " & strPrivateName & "=" & strParamName & _ | |
" : End Property : " | |
End Function | |
Private Function parse() | |
Dim i, Keys, Items | |
Keys = m_objProperties.Keys | |
Items = m_objProperties.Items | |
Dim init, pstr | |
init = "" | |
pstr = "" | |
parse = "Class " & m_strName & " :" & _ | |
"Private Sub Class_Initialize() : " | |
Dim strPrivateName, strAvailableKeys | |
For i = 0 To m_objProperties.Count - 1 | |
strPrivateName = "m_var" & Keys(i) | |
init = init & strPrivateName & "=""" & _ | |
Replace(CStr(Items(i)(0)), """", """""") & """:" | |
pstr = pstr & "Private " & strPrivateName & " : " | |
strAvailableKeys = strAvailableKeys & Keys(i) & "," | |
If CInt(Items(i)(1)) > 0 Then ' ReadOnly | |
pstr = pstr & getReadOnlyCode(Keys(i)) | |
ElseIf CInt(Items(i)(1)) < 0 Then ' WriteOnly | |
pstr = pstr & getWriteOnlyCode(Keys(i)) | |
Else ' AccessAll | |
pstr = pstr & getReadOnlyCode(Keys(i)) & _ | |
getWriteOnlyCode(Keys(i)) | |
End If | |
Next | |
init = init & "m_strAvailableKeys = Replace(""," & _ | |
strAvailableKeys & """, "" "", """") : " | |
Dim hasstmt | |
hasstmt = "Private m_strAvailableKeys : " & _ | |
"Public Function hasattr_(ByVal key) : " & _ | |
"hasattr_ = CBool(InStr(m_strAvailableKeys," & _ | |
" "","" & key & "","") > 0) : " & _ | |
"End Function : " & _ | |
"Public Function getattr_(ByVal key, ByVal defaultValue) : " & _ | |
"If hasattr_(key) Then : getattr_ = Eval(key) : " & _ | |
"Else : getattr_ = defaultValue : End If : " & _ | |
"End Function : " | |
parse = parse & init & "End Sub : " & _ | |
hasstmt & pstr & "End Class" | |
End Function | |
Public Function getObject() | |
'Response.Write parse | |
Call Execute(parse) | |
Set getObject = Eval("New " & m_strName) | |
End Function | |
Public Sub invokeObject(ByRef obj) | |
Call Execute(parse) | |
Set obj = Eval("New " & m_strName) | |
End Sub | |
End Class | |
' Example: | |
Dim DynObj | |
Set DynObj = New DynamicObject | |
DynObj.add "Name", "WangYe", PROPERTY_ACCESS_READONLY | |
DynObj.add "HomePage", "http://wangye.org", PROPERTY_ACCESS_READONLY | |
DynObj.add "Job", "Programmer", PROPERTY_ACCESS_ALL | |
' | |
' 如果没有setClassName, | |
' 新创建的对象将会自动命名为AnonymousObject | |
' 但是如果创建多个对象,就必须指定名称 | |
' 否则就可能引起对象名重复的异常 | |
DynObj.setClassName "User" | |
Dim User | |
Set User = DynObj.GetObject() | |
' 或者 DynObj.invokeObject User | |
Response.Write User.Name | |
' Response.Write User.getName() | |
Response.Write User.HomePage | |
' Response.Write User.getHomePage() | |
Response.Write User.Job | |
' Response.Write User.getJob() | |
' 改变属性值 | |
User.Job = "Engineer" | |
' User.setJob "Engineer" | |
Response.Write User.getJob() | |
Set User = Nothing | |
Set DynObj = Nothing | |
' 有效的类名或属性名必须以字母开头 | |
Set DynObj = New DynamicObject | |
DynObj.setClassName "1User" ' ignore 此句将被忽略,因为类名不能以数字开始 | |
' ignore 下面这句也会被忽略,因为属性名不能以特殊符号开始 | |
DynObj.add "%Name", "WangYe", PROPERTY_ACCESS_READONLY | |
Set DynObj = Nothing | |
Dim DynObj | |
Set DynObj = New DynamicObject | |
DynObj.add "Name", "WangYe", PROPERTY_ACCESS_READONLY | |
Response.Write DynObj.hasattr_("Name") ' True | |
Response.Write DynObj.hasattr_("Favor") ' False | |
Set DynObj = Nothing | |
Dim DynObj | |
Set DynObj = New DynamicObject | |
DynObj.add "Name", "WangYe", PROPERTY_ACCESS_READONLY | |
Response.Write DynObj.getattr_("Name", "N/A") ' WangYe | |
Response.Write DynObj.getattr_("Favor", "N/A") ' N/A | |
Set DynObj = Nothing |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment