欢迎来到.net学习网

欢迎联系站长一起更新本网站!QQ:879621940

您当前所在位置:首页 » ASP.Net » 正文

热门阅读

你需要明白的.NET底层开发技术--2(反射,动态编译)

创建时间:2011年08月09日 13:56  阅读次数:(5425)
分享到:

反射是动态获取程序集的元数据的一种技术,这句话是做.NET程序员面试题目的一个的答案,你可选择记住它,就好比高中生物学里面讲到的细胞的结构的课程时,细胞由细胞膜,细胞质和细胞核组成。根据做程序的经验,Never ask why不是好习惯,即使是微软的API,有时候违反了调用约定,也会很抓狂。

请看下面这一段代码
Assembly assembly = Assembly.GetExecutingAssembly();

object entryForm = Activator.CreateInstance(formBaseType) as Form;

entryForm .MdiParent = this;
entryForm .Show();
entryForm .Activate();
代码的含义比较简单,从当前程序集中创建formBaseType类型,并调用它的方法。从方法名上来看,大概可以看出,这是一段MDI创建child子窗体,并显示子窗体的代码。
这段小代码,也是插件式框架的基本思路,请参考《Management Console 工具管理类软件通用开发框架(开放源码)》中的例子来体会它的用处。
在ERP/MIS系统中,应用反射的例子,实在是太多了。数据访问接口InventoryMovementDAL,借助于反射,来查找并调用它的实现类; 窗体也它的子窗体借助于反射来获取属性,传递值;ERP系统的整个框架,也是借助于反射搭建起来.

看下面的图,ERP的三个模块Paradox.ERP.SystemAdministration, Paradox.ERP.Engineering,Paradox.ERP.Inventory被Paradox.Framework.Kernal反射调用,如果再写一个Paradox.ERP.Sales的销售模块,几乎不需要改动,就可以让它被框架调用。

image

动态编译的例子,是应用到一个工资系统中. 请看图
image

对于如何解析工资的formular公式,有若干种办法,这里使有的是动态编译的方法。把每一个工资项看成是一个类型class的属性,Formular的内容则放到一个方法中去,当成表达式计算求职,最后应用反射,返回各属性的值即可。
public class FormularCalculation
    {
        public static object Build(string[] items, string formular)
        {
            string nameSpace = "A";
            string className = "FormularCalculation";
            string methodName = "Run";
            CSharpCodeProvider compiler = new CSharpCodeProvider();
            CompilerParameters paras = new CompilerParameters();
            paras.GenerateExecutable = false;
            paras.GenerateInMemory = true;
           
           StringBuilder classSrc = new StringBuilder();
            classSrc.Append(" using  System;"+Environment.NewLine);
            classSrc.Append(" namespace "+nameSpace+" { " + Environment.NewLine);
            classSrc.Append("public  class  " + className + "{ " + Environment.NewLine);
            foreach (string item in items)
            {
                classSrc.Append("public decimal " + item + ";" + Environment.NewLine);
            }
            classSrc.Append("public  void Run() { 基本工资=5000; " + Environment.NewLine);
             string [] format= Regex.Split(formular,Environment.NewLine);
             foreach (string prop in format)
             {
                 classSrc.Append(prop +" ;"+ Environment.NewLine);
             }
            classSrc.Append("}"+Environment.NewLine);
            classSrc.Append("}" + Environment.NewLine);
            classSrc.Append("}" + Environment.NewLine);
            string source = classSrc.ToString();

            CompilerResults result = compiler.CompileAssemblyFromSource(paras, source);
            CompilerErrorCollection error= result.Errors;
            Assembly assembly = result.CompiledAssembly;
            object eval = assembly.CreateInstance(nameSpace+"."+className);
            MethodInfo method = eval.GetType().GetMethod(methodName);
            object reobj = method.Invoke(eval, null);
            return eval;
        }
    }
调用方法如下
string[] items = { "应发合计","基本工资","奖金","福利费", "扣款合计","社保","税","实发合计","应税所得额"};
string formular=@ ”    应发合计=基本工资+ 奖金 + 福利费 - 扣款合计;
扣款合计=社保 + 税+ 应税所得额;
实发合计=应发合计-  扣款合计; ";
object obj = FormularCalculation.Build(items, formular);
            Type type = obj.GetType();
            foreach (PropertyInfo fi in type.GetProperties(BindingFlags.NonPublic | BindingFlags.Public
                                               | BindingFlags.Instance | BindingFlags.DeclaredOnly))
            {
                string value = fi.Name;  //取到计算后的各个属性的值
            }
动态编译还应用于软件的加密,在内存中产生加密程序的源代码,动态编译并运行,检测是否符合license授权。

烺齹 asT@w T鰁 g坃Y3
来源:
说明:所有来源为 .net学习网的文章均为原创,如有转载,请在转载处标注本页地址,谢谢!
【编辑:Zxw

打赏

取消

感谢您的支持,我会做的更好!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

最新评论

共有评论0条
  • 暂无任何评论,请留下您对本文章的看法,共同参入讨论!
发表评论:
留言人:
内  容:
请输入问题 55+14=? 的结果(结果是:69)
结  果: