获取 ProjectItem 的命名空间

Getting the namespace of a ProjectItem

我正在编写一个扩展 IModelGenerationExtension 的 VSIX 扩展,它在更新或生成实体数据模型后执行一些操作。

public class ModelGenerationExtension : IModelGenerationExtension
{
    public void OnAfterModelGenerated(ModelGenerationExtensionContext context)
    {
    }
    public void OnAfterModelUpdated(UpdateModelExtensionContext context)
    {
        //need namespace of context.ProjectItem here
    }
}

由于这是在实体数据模型上运行,因此 context.ProjectItem 将是一个 .edmx 文件 - 我们称其为 Model1.edmx。这将包含一个名为 Model1.tt 的文件,该文件又包含一些嵌套的 .cs 文件,每个文件都与一个实体相关联。

我需要做的是从 ProjectItem 中获取这些 .cs 文件之一的名称空间(所有实体都在同一名称空间中)。

我该怎么做?

我开发 VS 扩展已经有一段时间了,但我查看了一些关于如何搜索这些东西的旧代码。也许今天有更新的技术,但这是我所知道的:

首先,您应该通过遍历您为 Model1.edmx 获得的项目的子项 ProjectItems 来找到正确的文件,以找到 *.cs 文件:

ProjectItem tt = context.ProjectItem.ProjectItems.OfType<ProjectItem>()
                        .FirstOrDefault(item => item.Name == "Model1.tt");

ProjectItem cs = tt.ProjectItems.OfType<ProjectItem>()
                        .FirstOrDefault(item => item.Name.EndsWith(".cs"));

然后你可以使用这个ProjectItem csFileCodeModel来搜索第一个命名空间配置:

CodeNamespace nsp = cs.FileCodeModel.CodeElements.Cast<CodeElement>().
            OfType<CodeNamespace>().First();

在那里你应该有你的命名空间元素。 CodeNamespace 有一个 属性 Name 和一个 FullName

我根据我在旧代码中阅读的内容将其组合在一起,但现在无法对其进行测试。您需要添加错误处理,我不能 100% 确定您描述的文件层次结构是否真的像 ProjectItems 层次结构中那样重现。