.NET 动态加载程序集 (一)

我们先来看.net中与本几个重要的概念:

1)应用程序域,由 AppDomain 对象来表示,为执行托管代码提供隔离、卸载和安全边界。多个应用程序域可以在一个进程中运行;但是,在应用程序域和线程之间没有一对一的关联。多个线程可以属于一个应用程序域,尽管给定的线程并不局限于一个应用程序域,但在任何给定时间,线程都在一个应用程序域中执行。应用程序域通过使用 CreateDomain 方法来创建。AppDomain 实例用于加载和执行程序集 (Assembly)。当不再使用 AppDomain 时,可以将它卸载。AppDomain 类实现一组事件,这些事件使应用程序可以在加载程序集、卸载应用程序域或引发未处理的异常时进行响应。

2)程序集是 .NET 框架应用程序的生成块;程序集构成了部署、版本控制、重复使用、激活范围控制和安全权限的基本单元。程序集是为协同工作而生成的类型和资源的集合,这些类型和资源构成了一个逻辑功能单元。程序集为公共语言运行库提供它要用于识别类型实现的信息程序集旨在简化应用程序部署并解决在基于组件的应用程序中可能出现的版本控制问题ms-help://MS.NETFrameworkSDK.CHS/cpguidenf/html/cpconwhyuseassemblies.htm

程序集可以是静态的或动态的。静态程序集可以包括 .NET 框架类型(接口和类),以及该程序集的资源(位图、JPEG 文件、资源文件等)。静态程序集以 PE 文件格式存储在磁盘上。您还可以使用 .NET 框架来创建动态程序集,动态程序集直接从内存运行并且在执行前不存储到磁盘上。您可以在执行动态程序集后将它们保存在磁盘上。

3)运行库如何定位程序集

若要成功地部署 .NET 框架应用程序,必须了解公共语言运行库如何定位和绑定组成应用程序的程序集。默认情况下,运行库试图与生成应用程序使用的程序集的原版本绑定。这种默认行为可以由配置文件设置覆盖。

在试图定位程序集并解析程序集引用时,公共语言运行库将执行若干个步骤。以下几节中对每个步骤进行了解释。当描述运行库如何定位程序集时,通常使用“探测”一词;它是指基于名称和区域性定位程序集时使用的一组试探法。

(使用包含在 .NET 框架 SDK 中的程序集绑定日志查看器 (Fuslogvw.exe),来查看日志文件中的绑定信息)

当运行库试图解析对另一个程序集的引用时,就开始进行定位并绑定到程序集的进程。该引用可以是静态的,也可以是动态的。在生成时,编译器在程序集清单的元数据中记录静态引用。动态引用是由于调用各种方法而动态构造的,例如 System.Reflection.Assembly.Load 方法。

引用程序集的首选方式就是使用完全引用,包括程序集名称、版本、区域性和公钥标记(如果存在)。运行库就会按照本节后面描述的步骤,使用这些信息来定位程序集。无论引用是对静态程序集的引用还是对动态程序集的引用,运行库均使用相同的解析过程。

还可通过向调用方法仅提供有关程序集的部分信息的方式(例如仅指定程序集名称),对程序集进行动态引用。在这种情况下,仅在应用程序目录下搜索程序集,不进行其他检查。您可以使用不同加载程序集方法中的任何方法(例如 System.Reflection.Assembly.Load 或 AppDomain.Load)进行部分引用。如果希望运行库在全局程序集缓存和应用程序目录下检查引用的程序集,可以用 System.Reflection.Assembly.LoadWithPartialName 方法指定部分引用。有关部分绑定的更多信息,请参阅部分程序集引用

最后,可以使用诸如 System.Reflection.Assembly.Load 之类的方法进行动态引用并只提供部分信息;然后在应用程序配置文件中用 <qualifyAssembly> 元素限定该引用。该元素使您可以在应用程序配置文件中而不是在代码中提供完全引用信息,包括名称、版本、区域性和公钥标记(如果适用)。如果要在应用程序目录外完全限定对某个程序集的引用,或者如果要引用全局程序集缓存中的程序集,但又希望方便地在配置文件中而不是在代码中指定完全引用,就可以采用这一技术。

注意 此类型的部分引用不应用于几个应用程序共享的程序集。因为配置设置是应用于每一应用程序而不是每一个程序集的,所以使用此类型部分引用的共享程序集将要求使用该共享程序集的每一应用程序都要在其配置文件中具有限定信息。

运行库使用以下步骤来解析程序集引用:

1.通过检查适用的配置文件(包括应用程序配置文件、发行者策略文件和计算机配置文件),确定正确的程序集版本。如果配置文件位于远程计算机上,则运行库必须首先定位和下载应用程序配置文件。

2.检查程序集名是否以前已被绑定,如果已绑定,则使用以前加载的程序集。

3.检查全局程序集缓存。如果在其中找到了程序集,则运行库使用该程序集。

4.按以下步骤探测程序集

a.如果配置策略和发行者策略不影响原始引用,并且绑定请求是使用 Assembly.LoadFrom 方法创建的,则运行库检查位置提示。

b.如果在配置文件中找到了代码基,则运行库只检查该位置。如果该探测失败,则运行库确定绑定请求已失败,并且不再进行其他的探测。

c.使用探测部分中描述的试探法探测程序集。如果探测后没有找到程序集,则运行库请求 Windows 安装程序提供程序集。它用作一个即需即装功能。

注意 不对没有强名称的程序集进行版本检查,并且运行库也不在全局程序集缓存中检查没有强名称的程序集。

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您好!感谢您的提问。如果您想从程序加载自定义的邮箱(Mailbox),可以按照以下步骤进行操作: 1. 创建自定义邮箱类,继承自 MailboxType。 ``` public class MyMailbox : MailboxType { public MyMailbox(Settings settings, Config config) : base(settings, config) { // 可以在这里进行一些初始化操作 } // 创建邮箱实例 public override IMessageQueue Create(IActorRef owner, ActorSystem system) { // 返回自定义的邮箱实例 return new MyMessageQueue(); } } ``` 2. 创建自定义消息队列类,实现 IMessageQueue 接口。 ``` public class MyMessageQueue : IMessageQueue { // 实现 IMessageQueue 接口中的方法 // ... } ``` 3. 在程序中注册自定义邮箱。 ``` // 注册邮箱 var mailboxConfig = ConfigurationFactory.ParseString(@" akka.actor.mailbox.requirements { ""my-mailbox"" = ""MyNamespace.MyMailbox, MyAssemblyName"" } "); // 加载程序 var assembly = Assembly.LoadFrom("MyAssemblyName.dll"); // 创建 ActorSystem var system = ActorSystem.Create("MySystem", ConfigurationFactory.Load(mailboxConfig).WithFallback(ConfigurationFactory.FromAssembly(assembly))); ``` 其中,`MyNamespace.MyMailbox` 是自定义邮箱类的完整命名空间和类名,`MyAssemblyName` 是包含自定义邮箱类的程序名称。 在创建 ActorSystem 时,使用 `ConfigurationFactory.Load(mailboxConfig).WithFallback(ConfigurationFactory.FromAssembly(assembly))` 方法加载配置信息。这样,程序就可以从程序加载自定义邮箱了。 4. 在创建 Actor 时,指定使用自定义邮箱。 ``` var props = Props.Create<MyActor>().WithMailbox("my-mailbox"); var actor = system.ActorOf(props, "MyActor"); ``` 在创建 Actor 时,使用 `WithMailbox` 方法指定使用自定义邮箱。 希望这些信息能够帮助到您!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值