C#发现之旅:基于反射和动态编译的快速ORM框架(下)
2010-09-30 21:08:22 来源:WEB开发网这个函数的参数是生成的代码的名称空间的名称,保存代码文本的文件名和要处理的数据库实体对象类型列表。在函数中首先创建一个myWriter的代码文本书写器,输出导入名称空间的代码文本,输出命名空间的代码文本,然后遍历RecordTypes列表中的所有的实体对象类型,对每一个实体对象类型输出一个定义类的C#代码文本,类名就是 类型名称+ORMHelper,该类继承自RecordORMHelper类型。然后执行上述的生成TableName,RecordFieldNames,FillUpdateCommand,FillDelteCommand,FillInsertCommand和InnerReadRecord的C#代码文本的过程,这样就完成了针对一个实体对象类型的C#代码的生成过程。
当代码生成器完成工作后,内置的代码文本书写器myWriter中就包含了完整的C#代码文本。这个代码文本中包含了多个从RecordORMHelper类型派生的数据库操作帮助类型。这样我们就可以随即展开动态编译的操作了。
动态编译
在代码生成器成功的生成所有的C#源代码文本后,我们就可以执行动态编译了,函数MyFastORMFramework.BuildHelpers就是实现动态编译,其代码为
private int BuildHelpers( string strFileName )
{
System.Collections.ArrayList RecordTypes = new System.Collections.ArrayList();
foreach( Type RecordType in myRecordHelpers.Keys )
{
if( myRecordHelpers[ RecordType ] == null )
{
RecordTypes.Add( RecordType );
}
}//foreach
if( RecordTypes.Count == 0 )
return 0 ;
// 开始创建代码
string nsName = "Temp" + System.Guid.NewGuid().ToString("N");
// 生成C#代码
string strSource = GenerateCode(nsName, strFileName , RecordTypes );
// 编译临时生成的C#代码
System.Collections.Specialized.StringCollection strReferences = new System.Collections.Specialized.StringCollection();
System.CodeDom.Compiler.CompilerParameters options = new System.CodeDom.Compiler.CompilerParameters();
options.GenerateExecutable = false;
options.GenerateInMemory = true ;
// 添加编译器使用的引用
System.Collections.ArrayList refs = new System.Collections.ArrayList();
foreach( Type t in RecordTypes )
{
refs.Add( t.Assembly.CodeBase );
}
refs.Add( this.GetType().Assembly.CodeBase );
refs.AddRange( new string[]{
"mscorlib.dll",
"System.dll" ,
"System.Data.dll" ,
});
for( int iCount = 0 ; iCount < refs.Count ; iCount ++ )
{
string strRef = ( string ) refs[ iCount ] ;
if( strRef.StartsWith("file:///"))
strRef = strRef.Substring( "file:///".Length );
if( options.ReferencedAssemblies.Contains( strRef ) == false )
{
options.ReferencedAssemblies.Add( strRef );
}
}
//string strSource = myWriter.ToString();
// 调用C#代码编译器编译生成程序集
Microsoft.CSharp.CSharpCodeProvider provider = new Microsoft.CSharp.CSharpCodeProvider();
// 若使用微软.NET框架.1则调用ICodeCompiler
//System.CodeDom.Compiler.ICodeCompiler compiler = provider.CreateCompiler();
//System.CodeDom.Compiler.CompilerResults result = compiler.CompileAssemblyFromSource( options , strSource );
// 若使用VS.NET2005或更新版本编译程序会在这里形成一个编译警告信息,
// 则可以将上面两行代码去掉而使用下面的代码
System.CodeDom.Compiler.CompilerResults result = provider.CompileAssemblyFromSource(options, strSource);
if( result.Errors.Count == 0 )
{
System.Reflection.Assembly asm = result.CompiledAssembly ;
myAssemblies.Add( asm );
// 创建内置的数据库对象操作对象
foreach( Type RecordType in RecordTypes )
{
Type t = asm.GetType( nsName + "." + RecordType.Name + "ORMHelper" );
RecordORMHelper helper = ( RecordORMHelper ) System.Activator.CreateInstance( t );
myRecordHelpers[ RecordType ] = helper ;
System.Console.WriteLine("FastORM为\"" + RecordType.FullName + "\"创建操作帮助对象");
}
}
else
{
System.Console.WriteLine("ORM框架动态编译错误" );
foreach( string strLine in result.Output )
{
System.Console.WriteLine( strLine );
}
}
provider.Dispose();
return RecordTypes.Count ;
}
更多精彩
赞助商链接