Шрифт:
Интервал:
Закладка:
using System;
using CommonSnappableTypes;
namespace CSharpSnapIn
{
[CompanyInfo(CompanyName = "FooBar", CompanyUrl = "www.FooBar.com")]
public class CSharpModule : IAppFunctionality
{
void IAppFunctionality.DoIt()
{
Console.WriteLine("You have just used the C# snap-in!");
}
}
}
Обратите внимание на явную реализацию интерфейса IAppFunctionality (см. главу 8). Поступать так необязательно; тем не менее, идея заключается в том, что единственной частью системы, которая нуждается в прямом взаимодействии с упомянутым интерфейсным типом, будет размещающее приложение. Благодаря явной реализации интерфейса IAppFunctionality метод DoIt() не доступен напрямую из типа CSharpModule.
Построение оснастки на Visual Basic
Теперь перейдите к проекту VBSnapIn. Удалите файл Class1.vb и добавьте новый файл по имени VBSnapIn.vb. Код Visual Basic столь же прост:
Imports CommonSnappableTypes
<CompanyInfo(CompanyName:="Chucky's Software", CompanyUrl:="www.ChuckySoft.com")>
Public Class VBSnapIn
Implements IAppFunctionality
Public Sub DoIt() Implements CommonSnappableTypes.IAppFunctionality.DoIt
Console.WriteLine("You have just used the VB snap in!")
End Sub
End Class
Как видите, применение атрибутов в синтаксисе Visual Basic требует указания угловых скобок (<>), а не квадратных ([]). Кроме того, для реализации интерфейсных типов заданным классом или структурой используется ключевое слово Implements.
Добавление кода для ExtendableApp
Последним обновляемым проектом является консольное приложение C# (MyExtendableApp). После добавления к решению консольного приложения MyExtendableApp и установки его как стартового проекта добавьте ссылку на проект CommonSnappableTypes, но не на CSharpSnapIn.dll или VbSnapIn.dll. Модифицируйте операторы using в начале файла Program.cs, как показано ниже:
using System;
using System.Linq;
(window.adrunTag = window.adrunTag || []).push({v: 1, el: 'adrun-4-390', c: 4, b: 390})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);
}
}
- Понимание SQL - Мартин Грубер - Базы данных