Работа со сборками, не имеющими ссылок на этапе компиляции

Иногда удобно явно загружать сборки .NET, на которые могут отсутствовать ссылки на этапе компиляции.

Если такая сборка является исполняемым файлом, который нужно просто запустить, достаточно вызвать метод ExecuteAssembly на текущем домене приложения. Метод ExecuteAssembly загружает исполняемый файл с использованием семантики LoadFrom, после чего вызывает его метод точки входа с передачей дополнительных аргументов командной строки.

Например:

string dir = AppDomain.CurrentDomain.BaseDirectory;

AppDomain.CurrentDomain.ExecuteAssembly (Path.Combine (dir, "test.exe"));

Метод ExecuteAssembly работает синхронным образом, т.е. вызывающий метод блокируется до тех пор, пока не завершится выполнение вызванной сборки. Для асинхронной работы метод ExecuteAssembly должен быть вызван в другом потоке или задаче.

Тем не менее, в большинстве случаев сборка, которую необходимо загрузить, является библиотекой. Применяемый подход заключается в вызове LoadFrom и работе с типами сборки посредством рефлексии.

Ниже приведен пример:

string ourDir = AppDomain.CurrentDomain.BaseDirectory;

string pluglnDir = Path.Combine (ourDir, "plugins");

Assembly a = Assembly.LoadFrom (Path.Combine (pluglnDir, "widget.dll"));

Type t = a.GetType ("Namespace.TypeName");

object widget = Activator.Createlnstance (t) ;

В коде использовался метод LoadFrom, а не LoadFile, чтобы обеспечить загрузку из той же папки любых закрытых сборок, на которые ссылается widget .dll. После этого из сборки извлекается нужный тип по имени и создается его экземпляр.

На следующем шаге можно было бы применить рефлексию для динамического вызова методов и доступа к свойствам объекта widget; мы покажем, как это делать, в следующей главе. Более простой и быстрый подход предусматривает приведение этого объекта к какому-нибудь типу, который воспринимается обеими сборками. Часто это интерфейс, определенный в общей сборке:

public interface IPluggable { void ShowAboutBox (); }

Теперь можно поступать следующим образом:

Type t = a.GetType ("Namespace.TypeName");

IPluggable widget = (IPluggable) Activator.Createlnstance (t);

widget.ShowAboutBox();

Поделитесь статьей со своими друзьями