3

在插件系统中,我实例化对象并根据一些传入的请求调用这些对象的方法,这些请求具有一些标识符(只是一个字符串)。在配置的帮助下,此标识符确定要加载哪个程序集、要实例化此程序集中的哪个类以及调用哪个方法。这些程序集被加载到一个单独的 AppDomain 中。这发生在这样创建的代理类中:

secondDomain.CreateInstanceFromAndUnwrap(Assembly.GetExecutingAssembly().CodeBase,
    typeof(SecondDomainProxy).FullName) as SecondDamainProxy;

在 SecondDomainProxy 类中,我加载与identifier上述相关的程序集:

string assemblyFileName = GetAssemblyFileNameFromConfig(identifier);
Assembly assembly = Assembly.LoadFrom(assemblyFileName);
// Instantiate and run something in assembly

问题:一旦程序集被加载,保持对这个 Assembly 对象的引用是否有意义?例如使用字典...

Dictionary<string, Assembly> _assemblyDict;

...并将上面的代码更改为:

Assembly assembly;
if (!_assemblyDict.TryGetValue(identifier, out assembly))
{
    string assemblyFileName = GetAssemblyFileNameFromConfig(identifier);
    assembly = Assembly.LoadFrom(assemblyFileName);
    _assemblyDict[identifier] = assembly;
}
// Instantiate and run something in assembly

我知道程序集是在第一次调用 Assembly.LoadFrom 之后加载的,直到 AppDomain 被卸载。(在我的例子中,第二个 AppDomain 的生命周期与主应用程序一样长。)那么这是否意味着对 Assembly.LoadFrom 的第二次调用很便宜,与字典查找一样便宜或几乎一样便宜?还是不调用 assembly.LoadFrom 而是使用保存的引用是否有缺点?

(我的感觉是,除非我有我没有的高性能要求(大约每 15 秒一个请求),否则这并不重要。但我可能是错的。)

感谢您提前反馈!

编辑:

Assembly是一个“普通”的 .NET 类。如果我没有对此类实例的任何引用,我认为它会被垃圾收集。但是程序集本身仍然处于加载状态。所以Assembly.LoadFrom至少需要创建一个Assembly 类的新实例,尽管在第二次这个实例创建可能基于已经加载的程序集。

我想补充一个问题:为给定程序集创建程序集对象是否需要大量反射,因此无论是否加载程序集总是很昂贵?

4

1 回答 1

1

不,没有必要。

加载到 AppDomain 后,可以使用底层 AppDomain 对象的 GetAssemblies() 方法访问该程序集,该方法返回任何已加载/可用的程序集,例如:http: //msdn.microsoft.com/en-US/library/system。 appdomain.getassemblies.aspx

卸载一个或多个程序集的唯一方法是卸载 AppDomain,方法是使用同一类的静态 Unload() 方法。

于 2010-12-25T06:13:27.637 回答