Шрифт:
Интервал:
Закладка:
На заметку! На момент написания главы в хранилище GitHub для MSBuild шло активное обсуждение относительно добавления возможности поддержки нестроковых параметров, что позволило бы добавлять атрибут CLSCompliant с использованием файла проекта вместо файла *.cs.
Установите несколько свойств (таких как Authors, Description), щелкнув правой кнопкой мыши на имени проекта в окне Solution Explorer, выберите в контекстном меню пункт Properties (Свойства) и в открывшемся окне свойств перейдите на вкладку Package. Кроме того, добавьте InternalsVisibleToAttribute, как делалось в главе 16. Содержимое вашего файла проекта должно выглядеть примерно так, как представленное ниже:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<Authors>Philip Japikse</Authors>
<Company>Apress</Company>
<Description>This is a simple car library with attributes</Description>
</PropertyGroup>
<ItemGroup>
<AssemblyAttribute Include="System.Runtime.CompilerServices.
InternalsVisibleToAttribute">
<_Parameter1>CSharpCarClient</_Parameter1>
</AssemblyAttribute>
</ItemGroup>
</Project>
После компиляции своего проекта перейдите в каталог objDebugnet5.0 и отыщите файл AttributedCarLibrary.AssemblyInfo.cs. Открыв его, вы увидите установленные свойства в виде атрибутов (к сожалению, они не особо читабельны в таком формате):
using System;
using System.Reflection;
[assembly: System.Runtime.CompilerServices.InternalsVisibleToAttribute
("CSharpCarClient")]
[assembly: System.Reflection.AssemblyCompanyAttribute("Philip Japikse")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[assembly: System.Reflection.AssemblyDescriptionAttribute("This is a
sample car library with attributes")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0")]
[assembly: System.Reflection.AssemblyProductAttribute("AttributedCarLibrary")]
(window.adrunTag = window.adrunTag || []).push({v: 1, el: 'adrun-4-390', c: 4, b: 390})[assembly: System.Reflection.AssemblyTitleAttribute("AttributedCarLibrary")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
И последнее замечание, касающееся атрибутов сборки: вы можете отключить генерацию файла AssemblyInfо.cs, если хотите управлять процессом самостоятельно.
Рефлексия атрибутов с использованием раннего связывания
Вспомните, что атрибуты остаются бесполезными до тех пор, пока к их значениям не будет применена рефлексия в другой части программного обеспечения. После обнаружения атрибута другая часть кода может предпринять необходимый образ действий. Подобно любому приложению "другая часть программного обеспечения" может обнаруживать присутствие специального атрибута с использованием либо раннего, либо позднего связывания. Для применения раннего связывания определение интересующего атрибута (в данном случае VehicleDescriptionAttribute) должно находиться в клиентском приложении на этапе компиляции. Учитывая то, что специальный атрибут определен в сборке AttributedCarLibrary как открытый класс, раннее связывание будет наилучшим выбором.
Чтобы проиллюстрировать процесс рефлексии специальных атрибутов, вставьте в решение новый проект консольного приложения по имени VehicleDescriptionAttributeReader. Добавьте в него ссылку на проект AttributedCarLibrary. Выполните приведенные далее команды CLI (каждая должна вводиться по отдельности):
dotnet new console -lang c# -n VehicleDescriptionAttributeReader -o .
VehicleDescriptionAttributeReader -f net5.0
dotnet sln .Chapter17_AllProjects.sln add .VehicleDescriptionAttributeReader
dotnet add VehicleDescriptionAttributeReader reference .AttributedCarLibrary
Поместите в файл Program.сs следующий код:
using System;
using AttributedCarLibrary;
Console.WriteLine("***** Value of VehicleDescriptionAttribute *****n");
ReflectOnAttributesUsingEarlyBinding();
Console.ReadLine();
static void ReflectOnAttributesUsingEarlyBinding()
{
// Получить объект Type, представляющий тип Winnebago.
Type t = typeof(Winnebago);
// Получить все атрибуты Winnebago.
object[] customAtts = t.GetCustomAttributes(false);
// Вывести описание.
foreach (VehicleDescriptionAttribute v in customAtts)
{
Console.WriteLine("-> {0}n", v.Description);
- Понимание SQL - Мартин Грубер - Базы данных