Реальное использование пользовательских атрибутов.NET
Для каких вещей вы использовали пользовательские атрибуты.NET в реальном мире?
Я прочитал несколько статей о них, но я никогда не использовал настраиваемые атрибуты.
Я чувствую, что могу пропустить их, когда они могут быть полезны.
Я говорю об атрибутах, которые вы создаете, а не о тех, которые уже включены в структуру.
7 ответов
Я использовал их "пользовательские" атрибуты для проверки (т. Е. Пометил поле для проверки своей собственной "проверкой кредитной карты") и собственные анализаторы LinqToLucene, которые я написал (т. Е. Указав, какой анализатор использовать в данном поле),
Код проверки, например, будет выглядеть примерно так:
public class Customer
{
[CreditCardValidator]
string creditCardNumber;
[AddressValidator]
string addressLineOne
}
Когда объект, указанный выше, проверяется, каждое поле проверяется соответствующим валидатором благодаря атрибуту "custom".
В материале LinqToLucene, который я написал, пользовательские атрибуты хороши тем, что позволяют находить (посредством отражения) определенные поля во время выполнения. Например, если у вас есть объект customer, вас может заинтересовать получение всех свойств, помеченных как "index me": пользовательский атрибут позволяет вам легко это сделать, поскольку он предоставляет метаданные об объекте таким образом, чтобы легко запросить.
Я создал механизм сценариев и пометил различные методы с помощью атрибута [Command]. Это означало, что эти функции были доступны скриптовому движку.
Пример:
[Command(HelpText = "Lists active users")]
void ListUsers(void)
{
}
[Command(HelpText = "Terminate a specific user's connection")]
void EndConnection(int userID)
{
}
И как используется:
MyScriptEngine>> Help
Available Commands are:
ListUsers: Lists active users
EndConnection {userID}: Terminate a specific user's connection
MyScriptEngine>> EndConnection 3
User 3 (Michael) has had his connection terminated.
MyScriptEngine>>
Среди прочего, я использовал их для указания EBNF, который читается во время выполнения, для создания пользовательских анализаторов на лету, а также для указания метаданных о полях для базы данных.
Я нахожу один "шаблон", который я обычно использую пользовательскими атрибутами, чтобы заменить перечисления, особенно когда есть зависимость от перечисления в различных местах кода.
Например, у меня может быть перечисление для состояния объекта. Исходя из этого состояния, у меня может быть 3 или 4 разных места в коде, которые я бы сделал "переключением" этого перечисления и выполнил какую-то операцию. Некоторые другие разработчики могут легко внести ошибку, добавив новое перечисление, но не обрабатывая ни один из операторов switch где-то еще в коде.
Поэтому, чтобы избежать этого, я создаю пользовательские атрибуты, объявленные для статического класса. Пользовательские атрибуты загружаются в статический конструктор класса в словарь, и все места в коде используют словарь вместо операторов switch. Конструктор пользовательских атрибутов содержит "жестко запрограммированные" значения для каждого оператора switch.
Я использовал его в одной из сред ORM, которую я разработал на основе шаблона ActiveRecord. Это та же самая реализация, которая доступна в LINQ, проекте Castle и т. Д.
Фреймворк назывался "SkyFramework", но он не был открытым исходным кодом.
Например, просто грубый пример...
Подобные примеры вы найдете и в других проектах с открытым исходным кодом.
[Sky.Table ("user")] public class User { [Sky.Column ("username")] public string UserName; [Sky.Column ("pwd")] public string Password; }
ПРИМЕЧАНИЕ. Атрибуты "Таблица", "Столбцы" в то время были пользовательскими атрибутами.
Механизм ActiveRecord анализирует объект для этих атрибутов и генерирует соответствующие функции для CRUD... и т. Д....
Точно так же я разработал некоторые пользовательские атрибуты для идентификации частей кода, которые необходимо сравнить... например.
[Sky.BenchMark()] public void LongRunningMethod(..) { }
Методы, отмеченные вышеуказанными атрибутами, автоматически помечаются, и создается журнал. Это были некоторые более ранние реализации.
По этой теме доступна книга Apress. Прикладные атрибуты.NET, которые могут быть вам полезны.
Я пока не нашел использования пользовательских атрибутов. Было несколько ситуаций, когда я думал, что они могут быть подходящими, но не использовал их, потому что, очевидно, отражение при чтении пользовательских атрибутов довольно дорого.
Я поместил настраиваемые атрибуты в классы внутри подключаемых библиотек DLL. Это позволяет платформе динамически обнаруживать доступные плагины, оценивать, представляют ли они интерес, а затем динамически загружать те, которые представляют интерес.
В нашем домене, например, плагины, которые моделируют определенные транспортные средства в семье. Один плагин для семейства транспортных средств может фактически моделировать несколько моделей транспортных средств в пределах семейства транспортных средств (например, "MX-6", "Probe"). Если идентификатор или имя модели включено в качестве массива пользовательских атрибутов, мы можем быстро игнорировать любые библиотеки DLL, которые даже не имеют пользовательских атрибутов, а затем дополнительно игнорировать любые библиотеки, которые не моделируют интересующий вас автомобиль.
Мне пришлось сериализовать некоторые объекты в пользовательский (устаревший) формат, и я использовал атрибуты, чтобы определить, какие поля следует сериализовать и как их форматировать. Затем у меня был сериализатор, который мог взять любой объект с этими атрибутами и использовать отражение для его форматирования.