У меня есть интерфейс маркера что-то вроде этого:
[AttributeUsage(AttributeTargets.Method, AllowMultiple=false, Inherited=true)]
public class MyAttribute : Attribute
{
}
И я хочу применить его к методам на различных классах в различных блоках...
Затем я хочу Получить MethodInfo для всех методов, которые имеют этот примененный атрибут. Я должен искать целый AppDomain и получить ссылку на все эти методы.
Я знаю, что мы можем получить все типы и затем получить все методы, но являемся там более быстрым/лучше способом сделать это?... или действительно ли это - самый быстрый способ для получения информации, в которой я нуждаюсь?
(Я использую ASP.NET MVC 1.0, C#./СЕТЬ 3.5),
Спасибо "куча"!
В конце концов, нет - вы должны их сканировать. Однако LINQ делает это довольно безболезненным.
var qry = from asm in AppDomain.CurrentDomain.GetAssemblies()
from type in asm.GetTypes()
from method in type.GetMethods()
where Attribute.IsDefined(method, typeof(MyAttribute))
select method;
Обратите внимание, что при этом сканируются только загруженные сборки «как есть».
Одна вещь, которую вы должны учитывать, - это дополнительный атрибут, который вы можете применить к классу / структуре, указывая, что отмечены ноль или более методов этого типа. Это должно дать вам улучшение производительности как минимум на порядок.
Если атрибут определяется пользователем (не встроен в платформу .NET), то при перечислении сборок для получения типов следует пропустить сборки инфраструктуры, такие как mscorlib и System.
Если вам действительно нужен прирост производительности, сделайте так, как Марк , а затем кешируйте результаты в файл. При следующей загрузке приложения, если кэшированный файл существует, он может загрузить соответствующий метод без анализа всех сборок.
Вот пример возможного файла кэша:
<attributeCache>
<assembly name='Assembly1' filename='Assembly1.dll' timestamp='02/02/2010'>
<type name='Assembly1.Type1'>
<method name='Method1'/>
</type>
</assembly>
<assembly name='Assembly2' filename='Assembly2.dll' timestamp='02/02/2010' />
</attributeCache>
Я тоже искал это несколько недель назад. Я думаю, что нет более простого пути.
Возможно, вам удастся немного улучшить его с помощью LINQ.