Когда я создавал такие пользовательские атрибуты, которые определяют некоторые метаданные класса, я часто создавал небольшую подпрограмму, которая сканирует все классы сборки с использованием отражения.
В моем текущем проекте я использую фреймворк IoC (другая история) и вместо того, чтобы конфигурировать его в пользовательском конфигурационном файле, я создал себе ComponentAttribute, который определяет, какому интерфейсу принадлежит класс. (С высоты птичьего полета: позже я спрашиваю инфраструктуру IoC об интерфейсе, и он знает, как создавать экземпляры классов, которые реализуют это, и как они сочетаются друг с другом)
Для настройки этой платформы IoC мне нужно вызвать члена определенного класса и сказать ему, какой класс существует для отображения интерфейса.
ioc.ConfigureMapping(classType, interfaceType)
Чтобы найти все эти сопоставления, я использую следующие два метода в одном из моих вспомогательных классов
internal static void Configure(IoCContainer ioc, Assembly assembly)
{
foreach (var type in assembly.GetTypes())
AddToIoCIfHasComponentAttribute(type, ioc);
}
internal static void AddToIoCIfHasComponentAttribute(Type type, IoC ioc)
{
foreach (ComponentAttribute att in type.GetCustomAttributes(typeof(ComponentAttribute), false))
{
ioc.ConfigureMapping(attribute.InterfaceType, type);
}
}
То, что я делаю здесь, перечисляет все типы сборок в первом методе, а затем вычисляет атрибут во втором.
Вернуться к вашей проблеме:
Используя подобный подход, вы можете найти все отмеченные классы и записать их в контейнер (ArrayList или аналогичный) вместе со всеми данными, которые вы определили в атрибуте (путь к странице и т. Д.).
Обновление (Ответ на комментарий)
Когда вы создаете свою программу в Visual Studio, у вас обычно есть один или несколько проектов. Для каждого проекта вы получите отдельную сборку (файл .dll или .exe). Приведенный выше код будет проверять все классы в пределах одной сборки. Таким образом, сборка представляет собой набор собранных файлов .cs. Таким образом, вы хотите искать сборку, а не каталог файлов .cs (которые являются исходным кодом и не являются частью запущенного приложения.)
Так что, вероятно, не хватает: как вы можете получить доступ к сборке из вашего кода, когда вы хотите искать классы? Вы просто берете ЛЮБОЙ известный вам класс (который находится в сборке / проекте, где находятся другие ваши классы) и получаете сборку, в которой он находится, вызывая
var assembly = typeof(MyDummyClass).Assembly;
и после этого вы будете вызывать что-то, полученное из кода выше
AnalyzeClasses(assembly)
и AnalyzeClasses будут выглядеть как
internal static void AnalyzeClasses(Assembly assembly)
{
foreach (var type in assembly.GetTypes())
AnalzyeSingleClass(type);
}
internal static void AnalzyeSingleClass(Type type)
{
foreach (MyCustomAttribute att in type.GetCustomAttributes(typeof(MyCustomAttribute), false))
{
Console.WriteLine("Found MyCustomAttribute with property {0} on class {1}",
att.MyCustomAttributeProperty,
type);
}
}
И вы просто позвоните, прежде чем запустить код приложения, например, прямо
вверху в main () (для приложений) или если сложно в продвинутом, вы также можете
звоните по требованию, когда вам нужны собранные данные. (Например, со страницы ASP.NET)