Чтение онлайн

ЖАНРЫ

Язык программирования C#9 и платформа .NET5
Шрифт:

Добавление кода для ExtendableApp

Последним обновляемым проектом является консольное приложение C# (

MyExtendableApp
). После добавления к решению консольного приложения
MyExtendableApp
и установки его как стартового проекта добавьте ссылку на проект
CommonSnappableTypes
, но не на
CSharpSnapIn.dll
или
VbSnapIn.dll
. Модифицируйте операторы
using
в начале файла
Program.cs
, как показано ниже:

using System;

using System.Linq;

using System.Reflection;

using CommonSnappableTypes;

Метод

LoadExternalModule
выполняет следующие действия:

• динамически загружает в память выбранную сборку;

• определяет, содержит ли сборка типы, реализующие интерфейс

IAppFunctionality
;

• создает экземпляр типа, используя позднее связывание.

Если обнаружен тип, реализующий

IAppFunctionality
, тогда вызывается метод
DoIt
и найденный тип передается методу
DisplayCompanyData
для вывода дополнительной информации о нем посредством рефлексии.

static void LoadExternalModule(string assemblyName)

{

Assembly theSnapInAsm = null;

try

{

// Динамически загрузить выбранную сборку.

theSnapInAsm = Assembly.LoadFrom(assemblyName);

}

catch (Exception ex)

{

// Ошибка при загрузке оснастки

Console.WriteLine($"An error occurred loading the snapin: {ex.Message}");

return;

}

// Получить все совместимые c IAppFunctionality классы в сборке.

var theClassTypes = theSnapInAsm

.GetTypes

.Where(t => t.IsClass && (t.GetInterface("IAppFunctionality") != null))

.ToList;

if (!theClassTypes.Any)

{

Console.WriteLine("Nothing implements IAppFunctionality!");

// Ни один класс не реализует IAppFunctionality!

}

// Создать объект и вызвать метод DoIt.

foreach (Type t in theClassTypes)

{

/// Использовать позднее связывание для создания экземпляра типа.

IAppFunctionality itfApp =

(IAppFunctionality)
theSnapInAsm.CreateInstance(t.FullName,
true);

itfApp?.DoIt;

// Отобразить информацию о компании.

DisplayCompanyData(t);

}

}

Финальная

задача связана с отображением метаданных, предоставляемых атрибутом
[CompanyInfo]
. Создайте метод
DisplayCompanyData
, который принимает параметр
System.Туре
:

static void DisplayCompanyData(Type t)

{

// Получить данные [CompanyInfo].

var compInfo = t

.GetCustomAttributes(false)

.Where(ci => (ci is CompanyInfoAttribute));

// Отобразить данные.

foreach (CompanyInfoAttribute c in compInfo)

{

Console.WriteLine($"More info about {c.CompanyName}

can be found at {c.CompanyUrl}");

}

}

Наконец, модифицируйте операторы верхнего уровня следующим образом:

Console.WriteLine("***** Welcome to MyTypeViewer *****");

string typeName = "";

do

{

Console.WriteLine("\nEnter a snapin to load");

// Введите оснастку для загрузки

Console.Write("or enter Q to quit: ");

// или Q для завершения

// Получить имя типа.

typeName = Console.ReadLine;

// Желает ли пользователь завершить работу?

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

{

break;

}

// Попытаться отобразить тип.

try

{

LoadExternalModule(typeName);

}

catch (Exception ex)

{

// Найти оснастку не удалось.

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

}

}

while (true);

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

Резюме

Рефлексия является интересным аспектом надежной объектно - ориентированной среды. В мире .NET Core службы рефлексии вращаются вокруг класса

System.Туре
и пространства имен
System.Reflection
. Вы видели, что рефлексия — это процесс помещения типа под "увеличительное стекло" во время выполнения с целью выяснения его характеристик и возможностей.

Поделиться с друзьями: