check the example inhttp://www.oreilly.com/catalog/progcsharp/chapter/ch18.htmlorDynamic Code Generation and Code Compilation http://www.codeproject.com/dotnet/dynacodgen.asp
就是.net的反射机制吧。 利用反射可以实现元数据的查询和动态代码生成。
这是我的一个动态代码生成的例子,你可以参考一下:[STAThread] static void Main(string[] args) { // //equivalent of this code is: // public class Utilities // { // private string a; // public override string ToString(){return a;} // public Utilities(string name) {a = name;} // } // create assembly AssemblyName assemblyName = new AssemblyName(); assemblyName.Name = "Utilities"; assemblyName.Version = new Version("1.0.1.0");AssemblyBuilder assembly = Thread.GetDomain().DefineDynamicAssembly( assemblyName, AssemblyBuilderAccess.RunAndSave);// create module ModuleBuilder module; module = assembly.DefineDynamicModule("MainModule", "Utilities.dll");// create class Turnmissile.DynamicCode.Utilities TypeBuilder utilsTypeBldr =module.DefineType("Turnmissile.DynamicCode.Utilities", TypeAttributes.Class | TypeAttributes.Public, typeof(System.Object));// equal to: private string a; FieldBuilder nameFld = utilsTypeBldr.DefineField("a", typeof(string), FieldAttributes.PrivateScope);// equal to define of: public override string ToString(); MethodBuilder toStringMethod = utilsTypeBldr.DefineMethod("ToString", MethodAttributes.Public | MethodAttributes.Virtual, typeof(string), Type.EmptyTypes);// equal to: return a; ILGenerator toStringIL = toStringMethod.GetILGenerator(); toStringIL.Emit(OpCodes.Ldarg_0); toStringIL.Emit(OpCodes.Ldfld, nameFld); toStringIL.Emit(OpCodes.Ret);// equal to define of: public Utilities(string name) Type[] constructorParamList = {typeof(string)}; ConstructorInfo objectConstructor = (typeof(System.Object)).GetConstructor(new Type[0]);// equal to: a = name; ConstructorBuilder constructor = utilsTypeBldr.DefineConstructor( MethodAttributes.Public, CallingConventions.Standard, constructorParamList); ILGenerator constructorIL = constructor.GetILGenerator(); constructorIL.Emit(OpCodes.Ldarg_0); constructorIL.Emit(OpCodes.Call, objectConstructor); constructorIL.Emit(OpCodes.Ldarg_0); constructorIL.Emit(OpCodes.Ldarg_1); constructorIL.Emit(OpCodes.Stfld, nameFld); constructorIL.Emit(OpCodes.Ret);// create type Type utilsType = utilsTypeBldr.CreateType();// use this assembly object utils = Activator.CreateInstance(utilsType, new object[]{"New Object!"}); object name = utilsType.InvokeMember("ToString",BindingFlags.InvokeMethod, null, utils, null); Console.WriteLine("ToString() returned: "+ (string)name);// save assembly.Save("Utilities.dll");Console.ReadLine();}
http://www.codeproject.com/dotnet/dynacodgen.asp
利用反射可以实现元数据的查询和动态代码生成。
static void Main(string[] args)
{
// //equivalent of this code is:
// public class Utilities
// {
// private string a;
// public override string ToString(){return a;}
// public Utilities(string name) {a = name;}
// }
// create assembly
AssemblyName assemblyName = new AssemblyName();
assemblyName.Name = "Utilities";
assemblyName.Version = new Version("1.0.1.0");AssemblyBuilder assembly = Thread.GetDomain().DefineDynamicAssembly(
assemblyName, AssemblyBuilderAccess.RunAndSave);// create module
ModuleBuilder module;
module = assembly.DefineDynamicModule("MainModule", "Utilities.dll");// create class Turnmissile.DynamicCode.Utilities
TypeBuilder utilsTypeBldr =module.DefineType("Turnmissile.DynamicCode.Utilities",
TypeAttributes.Class | TypeAttributes.Public, typeof(System.Object));// equal to: private string a;
FieldBuilder nameFld = utilsTypeBldr.DefineField("a", typeof(string),
FieldAttributes.PrivateScope);// equal to define of: public override string ToString();
MethodBuilder toStringMethod = utilsTypeBldr.DefineMethod("ToString",
MethodAttributes.Public | MethodAttributes.Virtual, typeof(string), Type.EmptyTypes);// equal to: return a;
ILGenerator toStringIL = toStringMethod.GetILGenerator();
toStringIL.Emit(OpCodes.Ldarg_0);
toStringIL.Emit(OpCodes.Ldfld, nameFld);
toStringIL.Emit(OpCodes.Ret);// equal to define of: public Utilities(string name)
Type[] constructorParamList = {typeof(string)};
ConstructorInfo objectConstructor = (typeof(System.Object)).GetConstructor(new Type[0]);// equal to: a = name;
ConstructorBuilder constructor = utilsTypeBldr.DefineConstructor(
MethodAttributes.Public, CallingConventions.Standard,
constructorParamList);
ILGenerator constructorIL = constructor.GetILGenerator();
constructorIL.Emit(OpCodes.Ldarg_0);
constructorIL.Emit(OpCodes.Call, objectConstructor);
constructorIL.Emit(OpCodes.Ldarg_0);
constructorIL.Emit(OpCodes.Ldarg_1);
constructorIL.Emit(OpCodes.Stfld, nameFld);
constructorIL.Emit(OpCodes.Ret);// create type
Type utilsType = utilsTypeBldr.CreateType();// use this assembly
object utils = Activator.CreateInstance(utilsType,
new object[]{"New Object!"});
object name = utilsType.InvokeMember("ToString",BindingFlags.InvokeMethod, null, utils, null);
Console.WriteLine("ToString() returned: "+ (string)name);// save
assembly.Save("Utilities.dll");Console.ReadLine();}
CodeTypeDeclaration typedec=new CodeTypeDeclaration("hello");
ns.Types.Add(typedec); CodeConstructor cc=new CodeConstructor();//构造函数 cc.Attributes=MemberAttributes.Public; CodeEntryPointMethod entrymed=new CodeEntryPointMethod();//入口点方法
CodeMethodInvokeExpression express=new CodeMethodInvokeExpression(new CodeTypeReferenceExpression("System.Console"),"WriteLine",new CodePrimitiveExpression("HelloWorld")); entrymed.Statements.Add(express);
CodeMemberMethod getStr=new CodeMemberMethod();
getStr.Name="getWx";
getStr.Statements.Add(express); typedec.Members.Add(cc);
typedec.Members.Add(getStr);
typedec.Members.Add(entrymed);
CodeDomProvider provider=new CSharpCodeProvider();
ICodeGenerator cg=provider.CreateGenerator();
IndentedTextWriter itw=new IndentedTextWriter(new StreamWriter("c:\\111.cs",false));
try
{ cg.GenerateCodeFromCompileUnit(cunit,itw,new CodeGeneratorOptions());
}
finally
{
itw.Close();
}