Это хорошая или плохая идея - сохранять ссылки на объекты Assembly, чтобы избежать ненужных вызовов Assembly.LoadFrom? - PullRequest
3 голосов
/ 22 декабря 2010

В системе плагинов я создаю экземпляры объектов и вызываю методы этих объектов на основе некоторых входящих запросов, которые имеют некоторый идентификатор (просто строку).С помощью конфигурации этот идентификатор определяет, какую сборку загрузить, какой класс в этой сборке создать и какой метод вызвать.Сборки загружаются в отдельный домен приложений.Это происходит в прокси-классе, который создается следующим образом:

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 живет столько же, сколько основное приложение в моем случае.) Значит ли это, что второй вызов Assembly.LoadFrom является дешевым, таким же дешевым или почти таким же дешевым, как поиск в словаре?Или у него есть недостатки, чтобы НЕ вызывать Assembly.LoadFrom и использовать вместо этого сохраненную ссылку?

(Мне кажется, это не имеет значения, если у меня нет требований к высокой производительности, которых у меня нет (одинпримерно каждые 15 секунд). Но я могу ошибаться.)

Спасибо за отзыв заранее!

Редактировать:

Assemblyэто "нормальный" класс .NET.Я думаю, что если у меня нет ссылок на экземпляр этого класса, он получает мусор.Но сама сборка все еще загружена.Так что Assembly.LoadFrom нужно по крайней мере создать новый экземпляр класса Assembly, хотя во второй раз это создание экземпляра может быть основано на уже загруженной сборке.

Я хотел бы добавить вопрос:создание объекта сборки для данной сборки требует значительного отражения и поэтому всегда дорого, независимо от того, загружена сборка или нет?

1 Ответ

1 голос
/ 25 декабря 2010

Нет, это не обязательно.

После загрузки в домен приложений доступ к сборке можно получить с помощью метода GetAssemblies () базового объекта AppDomain, который возвращает любую загруженную / доступную сборку, s: http://msdn.microsoft.com/en-US/library/system.appdomain.getassemblies.aspx

Единственный способ выгрузить одну или несколько сборок - выгрузить домен приложений с помощью статического метода Unload () того же класса.

...