Книги онлайн и без регистрации » Разная литература » Язык программирования C#9 и платформа .NET5 - Эндрю Троелсен

Язык программирования C#9 и платформа .NET5 - Эндрю Троелсен

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 209 210 211 212 213 214 215 216 217 ... 407
Перейти на страницу:
требованию называется динамической загрузкой.

System.Reflection  определяет  класс  под  названием  Assembly. Используя этот  класс,  вы  можете  динамически  загружать  сборку,  а также  обнаружить  свойства самой сборки. Используя тип Assembly, вы можете динамически загружать сборки, а также  загружать  сборку,  расположенную  в  произвольном  месте.  По  сути,  класс Assembly предоставляет методы, позволяющие программно загружать сборки с диска.

Чтобы  проиллюстрировать  динамическую  загрузку,  создайте  новый  проект консольного приложения с именем ExternalAssemblyReflector. Ваша задача ― создать код, который запрашивает имя сборки (минус расширения) для динамической загрузки.  Вы  передадите  ссылку  на  сборку  в  вспомогательный  метод  под  названием DisplayTypes(),  который  просто  выведет  имена  каждого  класса,  интерфейса, структуры, перечисления и делегата. делегата, который он содержит. Код освежающе прост.

using System;

using System.Reflection;

using System.IO; // Для определения FileNotFoundException.

Console.WriteLine("***** External Assembly Viewer *****");

string asmName = "";

Assembly asm = null;

do

{

  Console.WriteLine("nEnter an assembly to evaluate");

                    // Пригласить ввести имя сборки.

  Console.Write("or enter Q to quit: "); // или Q для завершения

  // Получить имя сборки.

  asmName = Console.ReadLine();

  // Пользователь желает завершить программу?

  if (asmName.Equals("Q",StringComparison.OrdinalIgnoreCase))

  {

    break;

  }

  // Попробовать загрузить сборку.

  try

  {

    asm = Assembly.LoadFrom(asmName);

    DisplayTypesInAsm(asm);

  }

  catch

  {

    Console.WriteLine("Sorry, can't find assembly.");

                 // Сборка не найдена.

  }

} while (true);

static void DisplayTypesInAsm(Assembly asm)

{

  Console.WriteLine("n***** Types in Assembly *****");

  Console.WriteLine("->{0}", asm.FullName);

  Type[] types = asm.GetTypes();

  foreach (Type t in types)

  {

    Console.WriteLine("Type: {0}", t);

  }

  Console.WriteLine("");

}

Если вы хотите проводить рефлексию по CarLibrary.dll, тогда перед запуском приложения ExternalAssemblyReflector понадобится скопировать двоичный файл CarLibrary.dll (из предыдущей главы ) в каталог проекта (в случае применения Visual Studio Code) или в каталог binDebugnet5.0 самого приложения (в случае использования Visual Studio). После выдачи запроса введите CarLibrary (расширение необязательно); вывод будет выглядеть примерно так:

***** External Assembly Viewer *****

Enter an assembly to evaluate

or enter Q to quit: CarLibrary

***** Types in Assembly *****

->CarLibrary, Version=1.0.0.1, Culture=neutral, PublicKeyToken=null

Type: CarLibrary.MyInternalClass

Type: CarLibrary.EngineStateEnum

Type: CarLibrary.MusicMedia

Type: CarLibrary.Car

Type: CarLibrary.MiniVan

Type: CarLibrary.SportsCar

Метод LoadFrom() также может принимать абсолютный путь к файлу сборки, которую нужно просмотреть (скажем, С:MyAppMyAsm.dll). Благодаря этому методу вы можете передавать полный путь в своем проекте консольного приложения. Таким образом, если файл CarLibrary.dll находится в каталоге С:MyCode, тогда вы можете ввести С:MyCodeCarLibrary (обратите внимание, что расширение необязательно).

Рефлексия сборок инфраструктуры

Метод Assembly.Load() имеет несколько перегруженных версий. Одна из них разрешает указывать значение культуры (для локализованных сборок), а также номер версии и значение маркера открытого ключа (для сборок инфраструктуры). Коллективно многочисленные элементы, идентифицирующие сборку, называются отображаемым именем. Форматом отображаемого имени является строка пар "имя-значение", разделенных запятыми, которая начинается с дружественного имени сборки, а за ним следуют необязательные квалификаторы (в любом порядке). Вот как выглядит шаблон (необязательные элементы указаны в круглых скобках):

Имя (,Version = <старший номер>.<младший номер>.<номер сборки>.сномер редакции>)

(,Culture = <маркер культуры>) (,PublicKeyToken = <маркер открытого ключа>)

При создании отображаемого имени соглашение PublicKeyToken=null отражает тот факт, что требуется связывание и сопоставление со сборкой, не имеющей строгого имени. Вдобавок Culture="" указывает, что сопоставление должно осуществляться со стандартной культурой целевой машины. Вот пример:

// Загрузить версию 1.0.0.0 сборки CarLibrary, используя стандартную культуру

Assembly а = Assembly.Load(

"CarLibrary, Version=l.0.0.0, PublicKeyToken=null, Culture=""" );

// В C# кавычки должны быть отменены с помощью символа обратной косой черты

Кроме того, следует иметь в виду, что пространство имен System.Reflection предлагает тип AssemblyName, который позволяет представлять показанную выше строковую информацию в удобной объектной переменной. Обычно класс AssemblyName применяется вместе с классом System.Version, который представляет собой объектно-ориентированную оболочку для номера версии сборки. После создания отображаемого имени его затем можно передавать перегруженной версии метода Assembly.Load():

// Применение типа AssemblyName для определения отображаемого имени.

AssemblyName asmName;

asmName = new AssemblyName();

asmName.Name = "CarLibrary";

Version v = new Version("1.0.0.0");

asmName.Version = v;

Assembly a = Assembly.Load(asmName);

Чтобы загрузить сборку .NET Framework (не .NET Core), в параметре Assembly.Load() должно быть указано значение PublicKeyToken. В .NET Core это не требуется из-за того, что назначение строгих имен используется реже. Например, создайте новый проект консольного приложения по имени FrameworkAssemblyViewer, имеющий ссылку на пакет Microsoft.EntityFrameworkCore. Как вам уже известно, это можно сделать в интерфейсе командной строки .NET 5 (CLI):

dotnet new console -lang c# -n FrameworkAssemblyViewer

                   -o .FrameworkAssemblyViewer -f net5.0

dotnet sln .Chapter17_AllProjects.sln add .FrameworkAssemblyViewer

dotnet add .FrameworkAssemblyViewer

    package Microsoft.EntityFrameworkCore -v 5.0.0

Вспомните, что в случае ссылки на другую сборку копия этой сборки помещается в выходной каталог ссылаемого проекта. Скомпилируйте проект с применением CLI:

dotnet build

После создания проекта, добавления ссылки на EntityFrameworkCode и компиляции проекта сборку теперь можно загрузить и инспектировать. Поскольку количество типов в данной сборке довольно велико, приложение будет выводить только имена открытых перечислений, используя простой запрос LINQ:

using System;

using System.Linq;

using System.Reflection;

Console.WriteLine("***** The Framework Assembly Reflector App *****n");

//  Загрузить Microsoft.EntityFrameworkCore.dll

var displayName =

   "Microsoft.EntityFrameworkCore, Version=5.0.0.0,

    Culture="", PublicKeyToken=adb9793829ddae60";

  Assembly asm = Assembly.Load(displayName);

  DisplayInfo(asm);

  Console.WriteLine("Done!");

  Console.ReadLine();

private static void DisplayInfo(Assembly a)

{

  Console.WriteLine("***** Info about Assembly *****");

  Console.WriteLine($"Asm Name: {a.GetName().Name}" );      // Имя сборки

  Console.WriteLine($"Asm Version: {a.GetName().Version}"); // Версия сборки

  Console.WriteLine($"Asm Culture:

    {a.GetName().CultureInfo.DisplayName}"); // Культура сборки

  Console.WriteLine("nHere are the public enums:");

                    // Список открытых

1 ... 209 210 211 212 213 214 215 216 217 ... 407
Перейти на страницу:

Комментарии
Минимальная длина комментария - 20 знаков. В коментария нецензурная лексика и оскорбления ЗАПРЕЩЕНЫ! Уважайте себя и других!
Комментариев еще нет. Хотите быть первым?