首页 > Windows开发 > 详细

【译】在C#中获取程序集比你想得要困难

时间:2020-07-22 23:22:03      阅读:78      评论:0      收藏:0      [点我收藏+]

某一天我正在写一些反射代码,目的是遍历所有的程序集来查找一个特定的接口,然后在Startup中调用其上的一个方法。看起来这个功能似乎很简单,但是在现实中,却没有一个清晰的,简单的,适合各种情形的方式来获取一个程序集。这篇文章获取对某些人来说非常的枯燥,但是如果我能够帮助哪怕一个人来解决此类问题,那么这篇文章也是值得的。

说真的,由于有多种获取程序集的方法,我将不会说”使用这个方法”。很有可能,对于你的特定的工程来说,也许只有一种方式可以工作,所以依赖其他的方式是毫无意义的。让我们简单的对所有的方式做个测试,然后看看哪一个方法是最合理的。

使用AppDomain.GetAssemblies

你可能会遇到的第一个选项是AppDomain.GetAssemblies。它(看似)加载了在AppDomain中的所有程序集,基本上可以说加载了你项目使用到的每一个程序集。但是却存在着大量的警告。在.NET中程序集是延迟加载到AppDomain中的,它不可能一次性加载所有的程序集,而是等你调用了一个程序集中的方法/类的时候,它才会将它加载进来--也就是即时加载。这是合理的,因为如果你从不使用一个程序集的话,是没有理由加载它的。

但问题是在你调用AppDomain.GetAssemblies()的那个时间点上,如果你并没有调用某个特定的程序集的方法,它便不会被加载。现在如果你要为了Startup方法得到所有的程序集,很有可能你还没有调用到那个程序集,这就意味着它还没有加载到AppDomain,所以便获取不到这个接口方法。

用代码来说:

AppDomain.CurrentDomain.GetAssemblies(); // Does not return SomeAssembly as it hasn‘t been called yet. 
SomeAssembly.SomeClass.SomeMethod();
AppDomain.CurrentDomain.GetAssemblies(); // Will now return SomeAssembly. 

虽然这看起来是一个很有吸引力的选项,但是要知道,对于这个方法来说,时机是一切。

使用AssemblyLoad事件

因为你不能确保当你调用CurrentDomain.GetAssemblies()时所有程序集都被加载了,而实际上当AppDomain加载另一个程序集的时候有一个事件会运行。基本上说,当一个程序集被延迟加载的时候,你可以被通知到。它看起来像是这样:

AppDomain.CurrentDomain.AssemblyLoad += (sender, args) =>
{
    var assembly = args.LoadedAssembly;
};

如果你只是想当程序集加载的时候检查下一些东西,那这或许是一个不错的解决方案,但是这个过程在某个特定的点并不是必然会发生(在你的.NET Core app的Startup.cs类中并不会发生)。

 

【译】在C#中获取程序集比你想得要困难

原文:https://www.cnblogs.com/qianxingmu/p/13363193.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!