オートメーション オブジェクト モデルの階層図
オートメーション オブジェクト モデルの階層図 - MSDN Library
T4 Templateによるコード生成ではVisual Studioオートメーションオブジェクトモデルの、特にソリューション〜プロジェクト中の要素にアクセスする為、この表に記述されているオブジェクト構造を理解している必要がある。 (特に親子関係が重要になる。)
例) CodeClassオブジェクトからParentを辿り、CodeImportオブジェクト(記述されているusingの情報が含まれる)を取得する。
Util.ttより
/// <summary> /// CodeClass中のCodeImportを列挙します /// </summary> public IEnumerable<EnvDTE80.CodeImport> GetCodeImports(CodeClass codeClass) { //Error("codeClass = " + codeClass.FullName); if (codeClass.Parent != null) { CodeNamespace nameSpace = (CodeNamespace)codeClass.Parent; if (nameSpace.Parent != null) { EnvDTE80.FileCodeModel2 codeModel2 = (EnvDTE80.FileCodeModel2)nameSpace.Parent; for (int i = 1; i < codeModel2.CodeElements.Count; i++) { EnvDTE80.CodeElement2 codeElement = (CodeElement2)codeModel2.CodeElements.Item(i); if ( codeElement.Kind == vsCMElement.vsCMElementImportStmt ) { EnvDTE80.CodeImport codeImport = (EnvDTE80.CodeImport)codeElement; yield return codeImport; } } } } }
注意しなければならないのは冒頭リンクのオブジェクト階層ではCodeElement内部にも階層があることが判らないことだ。例えば図ではCodeNamespaceオブジェクトとCodeImportオブジェクトはフラットな階層に存在しているように見えるが、コードを見れば判るように実際にはCodeModel2>CodeNamespace>CodeImportという階層が存在する。
階層構造とその独特の実装(バインディング)が理解できていないと私のようにMSDN Libraryに掲載されているプロパティだから取得できるのだろうと、延々とエラーを出すことになる。 :(