一个工程Project,一个Reff.CS文件(文件中定义了几个类,类名是固定的,但字段可能变),因为Reff.CS可能经常会变,所以Project中没有把Reff.CS包含进来,现在我要在Project中的执行阶段,先编译Reff.CS,生成一个DLL文件,然后动态地把DLL文件包含近来,通过反射取得Reff.CS中定义的那些类的类型。如果做,大家指点一下,比如说编译,如何动态地编译,不要再启动一个进程调用csc.exe编译,这样感觉很不好。

解决方案 »

  1.   

    System.Reflection.Emit 命名空间包含允许编译器或工具发出元数据和 Microsoft 中间语言 (MSIL) 并可选择在磁盘上生成 PE 文件的类。这些类的主要客户端是脚本引擎和编译器。ms-help://MS.MSDNQTR.2003FEB.2052/cpref/html/frlrfSystemReflectionEmit.htm点的大碗都没有空的,人家看你得题目有搞头,自然会进来帮你,如果没搞头,点名也不行,:)
      

  2.   

    你编译代码必须用程序啥,不用csc那也要用其它的编译器。
    所以只有新开一个进程来编译。
      

  3.   

    好像用系统的API也可以实现编译吧
      

  4.   

    参考CodeDom(动态编译),Reflection(反射)里面的类
      

  5.   

    用CodeDOM命名空间下的类可以动态编译,使用可以用Assembly.Load获得程序集。问题是你这样做什么?如果字段只是做为存储,你每次用反射来存/取值,则用Hashtable已经足够;又不能用Object.Property来操作;如果是用于动态绑定到列表,完全可以用ITypedList接口或动态生成DataTable之类的方法,没必要搞这么复杂吧???
    以上仅个人意见。
      

  6.   

    try
    {
    System.Net.WebClient wc = new System.Net.WebClient();//通过此类传输数据和接受方法
    System.IO.Stream stream = wc.OpenRead(url+"?WSDL");//读取webservice的内容
    System.Web.Services.Description.ServiceDescription sd = System.Web.Services.Description.ServiceDescription.Read(stream);//格式化xml文档
    //生成客户端代理
    System.Web.Services.Description.ServiceDescriptionImporter sdi = new System.Web.Services.Description.ServiceDescriptionImporter();


    #region 增加定义的命名空间
    sdi.AddServiceDescription(sd,"","");
    System.CodeDom.CodeNamespace cn = new System.CodeDom.CodeNamespace(@namespace);
    System.CodeDom.CodeCompileUnit ccu = new System.CodeDom.CodeCompileUnit();
    ccu.Namespaces.Add(cn);
    sdi.Import(cn,ccu);
    #endregion //定义编译生成环境
    Microsoft.CSharp.CSharpCodeProvider csc = new Microsoft.CSharp.CSharpCodeProvider();
    System.CodeDom.Compiler.ICodeCompiler icc = csc.CreateCompiler();
    System.CodeDom.Compiler.CompilerParameters cplist = new System.CodeDom.Compiler.CompilerParameters();
    cplist.GenerateExecutable = false;
    cplist.GenerateInMemory = true;
    cplist.ReferencedAssemblies.Add("System.dll");
    cplist.ReferencedAssemblies.Add("System.XML.dll");
    cplist.ReferencedAssemblies.Add("System.Web.Services.dll");
    cplist.ReferencedAssemblies.Add("System.Data.dll"); //编译上面生成的客户端代码
    System.CodeDom.Compiler.CompilerResults cr = icc.CompileAssemblyFromDom(cplist, ccu); //编译错误的处理
    if(true == cr.Errors.HasErrors)
    {
    System.Text.StringBuilder sb = new System.Text.StringBuilder();
    foreach(System.CodeDom.Compiler.CompilerError ce in cr.Errors)
    {
    sb.Append(ce.ToString());
    sb.Append(System.Environment.NewLine);
    }
    throw new Exception(sb.ToString());
    } //具体调用
    System.Reflection.Assembly assembly = cr.CompiledAssembly;
    Type t = assembly.GetType(@namespace+"."+classname,true,true);
    object obj = Activator.CreateInstance(t);
    System.Reflection.MethodInfo mi = t.GetMethod(methodname);
    return mi.Invoke(obj,args);
    }
    catch
    {

    // throw new Exception(ex.InnerException.Message,new Exception(ex.InnerException.StackTrace));
    return null;
    }
      

  7.   

    bitsbird(一瓢 在路上...),你好,请问假如web service只是提供了一个wsdl文件(webservice.wsdl),那么这两句如何写? System.Net.WebClient wc = new System.Net.WebClient();//通过此类传输数据和接受方法
    System.IO.Stream stream = wc.OpenRead(url+"?WSDL");//读取webservice的内容
      

  8.   

    bitsbird(一瓢 在路上...),解释一下楼上的疑问
      

  9.   

    关注下面的疑问:请问假如web service只是提供了一个wsdl文件(webservice.wsdl),那么这两句如何写?System.Net.WebClient wc = new System.Net.WebClient();//通过此类传输数据和接受方法
    System.IO.Stream stream = wc.OpenRead(url+"?WSDL");//读取webservice的内容
      

  10.   

    没啥说头的,肯定用csc编译成dll,然后输出到指定目录。然后loadassembly,加进来。预先定义好interface用起来还能方便点。不用csc的做法我没看到过那些高人貌似米空啊~~
      

  11.   

    string fspec = Application.ExecutablePath.Substring(0, Application.ExecutablePath.LastIndexOf(@"\"));fspec += @"\CompileClass.cs";

    Microsoft.CSharp.CSharpCodeProvider csc = new Microsoft.CSharp.CSharpCodeProvider();
    ICodeGenerator gen = csc.CreateGenerator();
    ICodeParser icp = csc.CreateParser();
    if(icp == null)
    {
    MessageBox.Show("icp is null");
    }
    CodeCompileUnit ccu = new CodeCompileUnit();
    using (FileStream fs = new FileStream(fspec, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
    {
    using (StreamReader sr = new StreamReader(fs))
    {
    MessageBox.Show(sr.ReadToEnd().ToString());
    ccu = icp.Parse(sr);
    }
    }

    System.CodeDom.Compiler.ICodeCompiler icc = csc.CreateCompiler();
    System.CodeDom.Compiler.CompilerParameters cplist = new System.CodeDom.Compiler.CompilerParameters();
    cplist.GenerateExecutable = false;
    cplist.GenerateInMemory = true;
    cplist.ReferencedAssemblies.Add("System.dll");
    cplist.ReferencedAssemblies.Add("System.XML.dll");
    cplist.ReferencedAssemblies.Add("System.Web.Services.dll");
    cplist.ReferencedAssemblies.Add("System.Data.dll");System.CodeDom.Compiler.CompilerResults cr = icc.CompileAssemblyFromDom(cplist, ccu);

    if(true == cr.Errors.HasErrors)
    {
    System.Text.StringBuilder sb = new System.Text.StringBuilder();
    foreach(System.CodeDom.Compiler.CompilerError ce in cr.Errors)
    {
    sb.Append(ce.ToString());
    sb.Append(System.Environment.NewLine);
    }
    throw new Exception(sb.ToString());
    }MessageBox.Show(cr.Output.ToString());
    System.Reflection.Assembly assembly = cr.CompiledAssembly;
    MessageBox.Show(assembly.FullName.ToString());
    //  Type t = assembly.GetType(nameSpace + "."+ "DICOMViewerTest_OUTPUTBean", true, true);
    Type[] tt = assembly.GetTypes();
    foreach(Type t in tt)
    {
    MessageBox.Show(t.FullName);

    }本来我想用ICodeParser icp = csc.CreateParser();去读取源文件,但这个接口没有实现,真的恶心,有谁知道还有没有其他的解决方案啊?
      

  12.   

    这个问题我已经完美解决,搂住想要留下email.