Получить все классы в проекте в Visual Studio Scaffolder

1

Я создаю инструмент для лесов для визуальной студии и должен представить список классов, которые происходят из определенного абстрактного класса, но только классы в активном проекте. У меня есть работа, но для запуска кода требуется визуальная студия.

ICodeTypeService codeTypeService = (ICodeTypeService)Context
                    .ServiceProvider.GetService(typeof(ICodeTypeService));

var types = codeTypeService.GetAllCodeTypes(Context.ActiveProject);

foreach (var type in types)
{
    type.
    if (type.Kind == vsCMElement.vsCMElementClass)
    {
        foreach (var d in type.Bases)
        {
            var dClass = d as CodeClass;
            var name = type.Name;
            if (dClass.Name == "MyAbstractClass")
            {
                if (type.Namespace.Name.Contains(Context.ActiveProject.Name))
                {
                    yield return type.Name;
                }
            }

        }
    }
}

Поэтому мне нужно сделать проверку пространства имен, когда он найдет подходящий класс, чтобы убедиться, что он находится в моем проекте. Мне кажется, что я делаю много ненужной работы. Это пример, который они дают с проектом визуальной студии шаблона:

ICodeTypeService codeTypeService = (ICodeTypeService)Context
                    .ServiceProvider.GetService(typeof(ICodeTypeService));

return codeTypeService
    .GetAllCodeTypes(Context.ActiveProject)
    .Where(codeType => codeType.IsValidWebProjectEntityType())
    .Select(codeType => new ModelType(codeType));

является ли режим codetypes правильным способом для этого?

EDIT В основном, когда он ищет классы, он не просто делает это в текущем активном проекте, но также выполняет поиск по всем указанным проектам. Вот почему я должен проверять пространство имен, поэтому получаю результаты только от активного проекта. Я считаю, что это замедлилось, потому что проекты, на которые ссылаются, достаточно велики, поэтому он делает чертовски много ненужной работы...

  • 0
    Можете ли вы определить «немного времени», также вы рассматривали Рослин для этого? Похоже, что если скорость это то, что вы ищете, это был бы путь.
  • 0
    Занимает около 10-15 секунд на моем компьютере, и Visual Studio переходит в режим «не отвечает» во время него. Так что не страшно, но ... да. И да, Roslyn выглядит как путь вперед, но это для VS2014, верно?
Показать ещё 5 комментариев
Теги:
visual-studio
envdte

1 ответ

2
Лучший ответ

Я заметил, что кто-то поддержал этот вопрос, напомнив мне, как мне заставить его работать немного быстрее. Рослин, как отметил Маслоу, классный, но Рослин не был доступен, когда я строил это расширение, за исключением предварительного просмотра, так что в основном это было просто бессмысленно.

Мое расширение находится на GitHub, вот соответствующий фрагмент кода: https://github.com/Hazzamanic/orchardizer/blob/master/Orchardization/UI/CustomViewModel.cs

Но в случае, если GitHub должен умереть/кто-то платит мне миллион долларов за мой код, вот соответствующий код...

/// <summary>
/// Recursively gets all the ProjectItem objects in a list of projectitems from a Project
/// </summary>
/// <param name="projectItems">The project items.</param>
/// <returns></returns>
public IEnumerable<ProjectItem> GetProjectItems(EnvDTE.ProjectItems projectItems)
{
    foreach (EnvDTE.ProjectItem item in projectItems)
    {
        yield return item;

        if (item.SubProject != null)
        {
            foreach (EnvDTE.ProjectItem childItem in GetProjectItems(item.SubProject.ProjectItems))
                yield return childItem;
        }
        else
        {
            foreach (EnvDTE.ProjectItem childItem in GetProjectItems(item.ProjectItems))
                yield return childItem;
        }
    }

}

Когда у вас есть все элементы проекта, вы можете их фильтровать. Это, кажется, отлично работает в довольно крупных проектах, хотя на самом деле у меня нет никаких масштабных проектов. В моем случае я хотел найти все классы с базовым классом DatMigrationImpl. Поэтому у меня был такой код:

var allClasses = GetProjectItems(Context.ActiveProject.ProjectItems).Where(v => v.Name.Contains(".cs"));
// check for .cs extension on each

foreach (var c in allClasses)
{
    var eles = c.FileCodeModel;
    if (eles == null)
        continue;
    foreach (var ele in eles.CodeElements)
    {
        if (ele is EnvDTE.CodeNamespace)
        {
            var ns = ele as EnvDTE.CodeNamespace;
            // run through classes
            foreach (var property in ns.Members)
            {
                var member = property as CodeType;
                if (member == null)
                    continue;

                foreach (var d in member.Bases)
                {
                    var dClass = d as CodeClass;
                    if (dClass == null)
                        continue;

                    var name = member.Name;
                    if (dClass.Name == "DataMigrationImpl")
                    {
                        yield return new Migration(member);
                    }
                }
            }
        }
    }
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню