程序集与应用程序域基础练习

1. 程序集

程序集是自我描述的安装单位。

程序集清单:描述了程序集和引用它所需要的所有信息。

查看程序集:ildasm 工具

程序集特性:VS会生成 AssemblyInfo.cs 文件,描述程序集特性,用于配置程序集清单。

用“C#”高级编程的例子来学习创建与动态加载程序集:

   public class CodeDriver
    {
        private string prefix =
            "using System;" +
            "public static class Driver" +
            "{" +
            "public static void run()" +
            "{";

        private string postfix =
            "}" +
            "}";

        public string CompileAndRun(string input, out bool hasError)
        {
            hasError = false;
            string returnData = null;

            CompilerResults results = null;
            using(var provider = new CSharpCodeProvider())
            {
                var options = new CompilerParameters();
                options.GenerateInMemory = true;

                var sb = new StringBuilder();
                sb.Append(prefix);
                sb.Append(input);
                sb.Append(postfix);

                results = provider.CompileAssemblyFromSource(options, sb.ToString());
            }

            if(results.Errors.HasErrors)
            {
                hasError = true;
                var errMessage = new StringBuilder();
                foreach(CompilerError error in results.Errors)
                {
                    errMessage.AppendFormat("{0} {1}", error.Line, error.ErrorText);
                }
                returnData = errMessage.ToString();
            }
            else
            {
                TextWriter temp = Console.Out;
                var writer = new StringWriter();
                Console.SetOut(writer);
                Type driverType = results.CompiledAssembly.GetType("Driver");   //通过反射在动态编译后的程序集中找到 Driver 这个静态类型

                driverType.InvokeMember("Run", BindingFlags.InvokeMethod | BindingFlags.Static
                    | BindingFlags.Public, null, null, null);                   //通过反射调用 Driver 的静态方法 Run
                returnData = writer.ToString();
            }

            return returnData;
        }
    }

  值得注意的是:只要实例化了一种类型的程序集,或者使用了该类型的一个方法,就会自动加载所引用程序集。

  另外,每次加载程序集,都会消耗越老越多的内存。如果要卸载程序集,就需要使用应用程序域。

  

2. 应用程序域

  应用程序域-可以确保在同一进程中不能访问另外一个应用程序的内存;多个应用程序可以运行在一个进程的多个应用程序域中。

  AppDomain 类用于创建与终止应用程序域,加载和卸载程序集。

示例:

程序集A:

    public class Demo
    {
        public Demo(int val1, int val2)
        {
            Console.WriteLine("Constructor with the value {0}, {1} in domain" +
                "{2} called", val1, val2, AppDomain.CurrentDomain.FriendlyName);
        }
    }

    public class Program
    {
        static void Main()
        {
            Console.WriteLine("Main in domain {0} called", AppDomain.CurrentDomain.FriendlyName);
            Console.ReadLine();
        }
    }

程序集B:

    class AProgram
    {
        static void Main(string[] args)
        {
            AppDomain currentDomain = AppDomain.CurrentDomain;
            Console.WriteLine(currentDomain.FriendlyName);
            AppDomain secondDomain = AppDomain.CreateDomain("New Domain");
            secondDomain.ExecuteAssembly("Delegate_Test.exe");
        }
    }

启动程序集B--输出结果:

使用 ExecuteAssembly 应该是执行另外一个程序集中的可执行文件,如果不是可执行文件呢?

还有另外一种更常用的方式。程序集B:

    class AProgram
    {
        static void Main(string[] args)
        {
            AppDomain currentDomain = AppDomain.CurrentDomain;
            Console.WriteLine(currentDomain.FriendlyName);
            AppDomain secondDomain = AppDomain.CreateDomain("New Domain");
            //secondDomain.ExecuteAssembly("Delegate_Test.exe");
            secondDomain.CreateInstance("Delegate_Test", "Assemblies_Test.Demo", true, BindingFlags.CreateInstance, null, new object[] { 2, 5 }, null, null);
            Console.ReadLine();
        }
    }
public ObjectHandle CreateInstance(string assemblyName, string typeName, bool ignoreCase, BindingFlags bindingAttr, Binder binder, object[] args, CultureInfo culture, object[] activationAttributes);

CreateInstance 返回的是 ObjectHandle,并不是实例。

进一步调用 Unwrap 方法返回背后的代理对象:

            var results = secondDomain.CreateInstance("Delegate_Test", "Assemblies_Test.Demo", true, BindingFlags.CreateInstance, null, new object[] {2, 5}, null, null);
            var assemblies_Test = results.Unwrap() as Assemblies_Test.Demo;
            assemblies_Test.hello();

3. 程序集卸载

  在主应用程序域中创建 新的应用程序域,并加载所需的程序集,在主应用程序域中,卸载新的域,就完成了程序集的卸载了。

时间: 2024-08-10 19:08:57

程序集与应用程序域基础练习的相关文章

C#语言基础原理及优缺点

一.原理: C#是专门为.net程序框架而创造的语言. .net框架有ms的.netFramework:Mono的.NetFramework(也是符合.net IL语言,CTS规范,CLS规范, CLR运行时库),mono程序可以运行在各种操作系统和游戏平台中运行(目前mono还不够成熟影响力较小). .net原理主要是编译的原理: IL中间语言, CLR运行时环境. .net程序组成体系主要概念:应用程序集,应用程序域. .net程序编译过程: 1)编译时:.netvs或mono编译器(或其它

SqlServer基础:约束

反射,一个很有用且有意思的特性.当动态创建某个类型的实例或是调用方法或是访问对象成员时通常会用到它,它是基于程序集及元数据而工作的,所以这一章我们来讨论一下程序集.反射如何工作.如何动态创建类型及对象等相关知识,甚至可以动态创建程序集. 第一节 应用程序域与程序集 通过本系列的前面章节,我们已经知道,Windows为每个进程分配独立的内存空间地址,各个进程之间不能直接相互访问.Windows对.NET的支持是以宿主和COM的形式实现的,基于.NET平台语言实现的代码文件使用Windows PE的

ASP.NET学习路线图(转)

如果你已经有较多的面向对象开发经验,跳过以下这两步: 第一步 掌握一门.NET面向对象语言,C#或VB.NET 我强烈反对在没系统学过一门面向对象(OO)语言的前提下去学ASP.NET. ASP.NET是一个全面向对象的技术,不懂OO,那绝对学不下去! 第二步 对.NET Framework类库有一定的了解 可以通过开发Windows Form应用程序来学习NET Framework.ASP.NET是建构在.NET Framework之上的技术,你对.NET Framework了解得越深,学习A

ASP.NET学习路线图

ASP.NET学习路线图 如果你已经有较多的面向对象开发经验,跳过以下这两步: 第一步 掌握一门.NET面向对象语言,C#或VB.NET 我强烈反对在没系统学过一门面向对象(OO)语言的前提下去学ASP.NET. ASP.NET是一个全面向对象的技术,不懂OO,那绝对学不下去! 第二步 对.NET Framework类库有一定的了解 可以通过开发Windows Form应用程序来学习NET Framework.ASP.NET是建构在.NET Framework之上的技术,你对.NET Frame

ASP.net 学习路线(详细)

ASP.net 学习路线(详细) 浏览:5632 | 更新:2013-12-13 16:33 | 标签: asp.net 百度经验:jingyan.baidu.com .net学习路线 入门篇1.         学习面向对象(OOP)的编程思想 许多高级语言都是面向对象的编程,.NET也不例外.如果您第一次接触面向对象的编程,就必须理解类.对象.字段.属性.方法和事件.封装.继承和多态性.重载.重写等概念.需要说明的是,微软的产品帮助文档做得非常完善,而且查询相当方便,入门者不得不看.安装完V

学习.net中,记下来

第一步 掌握一门.NET面向对象语言,C#或VB.NET 我强烈反对在没系统学过一门面向对象(OO)语言的前提下去学ASP.NET. ASP.NET是一个全面向对象的技术,不懂OO,那绝对学不下去! 第二步 对.NET Framework类库有一定的了解 可以通过开发Windows Form应用程序来学习.NET Framework.ASP.NET是建构在.NET Framework之上的技术,你对.NET Framework了解得越深,学习ASP.NET就越快. 举个例子:下面简单列出几个对掌

基于AppDomain的"插件式"开发

很多时候,我们都想使用(开发)USB式(热插拔)的应用,例如,开发一个WinForm应用,并且这个WinForm应用能允许开发人员定制扩展插件,又例如,我们可能维护着一个WinService管理系统,这个WinService系统管理的形形色色各种各样的服务,这些服务也是各个"插件式"的类库,例如: public interface IJob { void Run(DateTime time); } public class CollectUserInfo : IJob { public

【开源】.Net 动态脚本引擎NScript

开源地址: https://git.oschina.net/chejiangyi/NScript 开源QQ群: .net 开源基础服务  238543768 .Net 动态脚本引擎 NScript   用于解决.net环境windows系统下类似java中Grovvy的功能和方向.在互联网项目可以用来做一些功能,如动态营销活动(营销业务解耦和剥离),规则引擎,流程引擎,windows运维脚本,源码式插件开发等. 使用方式 包括exe Main方式,程序集方式,应用程序域三种方式. 最终编译文件

学习ASP.NET比较完整的流程!

如果你已经有较多的面向对象开发经验,跳过以下这两步:  第一步 掌握一门.NET面向对象语言,C#或VB.NET 我强烈反对在没系统学过一门面向对象(OO)语言的前提下去学ASP.NET. ASP.NET是一个全面向对象的技术,不懂OO,那绝对学不下去!  第二步 对.NET Framework类库有一定的了解 可以通过开发Windows Form应用程序来学习.NET Framework.ASP.NET是建构在.NET Framework之上的技术,你对.NET Framework了解得越深,