风舞残阳 2008-4-2 13:44
用.NET动态创建类的实例讲解
看了网上很多关于DotNet动态创建[wiki]类[/wiki]的实例的文章,我这里想总结一下,其实方法很简单,就是用“Activator.CreateInstance”。但是这个方法需要待创建的类的Type作为参数,为了获得该参数,可以利用[Assembly].GetType方法,这个方法只需要待创建的类的名称(名称字符串)就可以了,最后的问题就是要获得这个类所在的程序集。如何获得待创建的类所在程序集,那么就解决了这个问题。 大家可以参考http://www.cnblogs.com/ShadowK/archive/2006/11/14/560131.html,费了很多笔墨写了一个比较完整的动态构造类的设计器。其实,在获得程序集这个问题上,可以有更简单的办法,以下是我的做法。
利用Microsoft.VisualBasic.VBCodeProvider(),如果是C#可以用CSharpCodeProvider(),将类文件编译成为DLL文件,然后利用[Assembly].LoadFrom("DLL的绝对路径")加载该DLL。这样我们可以避免在那些创建DLL和Type的复杂代码。我告诉我的项目组成员这个例子后,强调要打开思路,Simpleisperfect,凡事都尽量找简便的方法来实现,客户永远不会为我们那些复杂的代码多花一分钱。
1.执行编译任务的方法:
以下是引用片段:
PublicSharedFunctionCompileExecutable()FunctionCompileExecutable(ByValsourceNameAsString,ByValDLLPathAsString,ByRefReturnDLLNameAsString)AsBoolean
DimsourceFileAsFileInfo=NewFileInfo(sourceName)
DimproviderAsCodeDomProvider=Nothing
DimcompileOkAsBoolean=False
'根据原文件的扩展名选择codeprovider
IfsourceFile.Extension.ToUpper(CultureInfo.InvariantCulture)=".CS"Then
provider=NewMicrosoft.CSharp.CSharpCodeProvider()
ElseIfsourceFile.Extension.ToUpper(CultureInfo.InvariantCulture)=".VB"Then
provider=NewMicrosoft.VisualBasic.VBCodeProvider()
Else
Console.WriteLine("原文件必须包含.cs或.vb扩展名")
EndIf
IfNotproviderIsNothingThen
'构造DLL文件的全路径
DimdllNameAsString=String.Format("{0}{1}.dll",_
DLLPath,_
sourceFile.Name.Replace(".","_"))
ReturnDLLName=dllName
DimcpAsCompilerParameters=NewCompilerParameters()
'设置编译控制参数
cp.GenerateExecutable=False'生成DLL,如果是True则生成exe文件
cp.OutputAssembly=dllName
cp.GenerateInMemory=False
cp.TreatWarningsAsErrors=False
'调用编译方法将原代码文件编译成DLL
DimcrAsCompilerResults=provider.CompileAssemblyFromFile(cp,_
sourceName)
Ifcr.Errors.Count%26gt;0Then
'显示编译错误
Console.WriteLine("编译错误{0}编译成{1}",_
sourceName,cr.PathToAssembly)
DimceAsCompilerError
ForEachceIncr.Errors
Console.WriteLine("{0}",ce.ToString())
Console.WriteLine()
Nextce
Else
'显示编译成功的消息
Console.WriteLine("原文件{0}编译成{1}成功完成.",_
sourceName,cr.PathToAssembly)
EndIf
'返回编译结果
Ifcr.Errors.Count%26gt;0Then
compileOk=False
Else
compileOk=True
EndIf
EndIf
ReturncompileOk
EndFunction 2.编译DLL,并动态创建类的实例。(这里类的原文件是Class1.vb文件,放在WebSite的App_Code文件夹中了,实际使用时可以放在任意物理位置。)
以下是引用片段:
DimstrSourceFileNameAsString=Server.MapPath(""/App_Code/Class1.vb")'类文件的全路径
DimstrDllPathAsString=Server.MapPath(""/App_Code")'编译后的DLL文件存放的位置
DimstrDllNameAsString=""'DLL的全路径(返回值)
CompileExecutable(strSourceFileName,strDllPath,strDllName)'编译原文件为DLL文件
DimaAs[Assembly]=[Assembly].LoadFrom(strDllName)'加载DLL
DimmyTypeAsSystem.Type=a.GetType("Class1")'获得Class1的Type
DimobjAsObject=Activator.CreateInstance(myType)'获得Class1的实例 3.Class1.vb原文件
以下是引用片段:
PublicClassClass1ClassClass1
PubliciAsInteger
EndClass