3

これが私がやりたいことです。

次のようなPOCOクラスを書きたい:

[AutoExtended]
public partial class Foo {
    public int Bar;
    public string Baz;
}

できれば私のソリューションの任意のファイルに入れます ([AutoExtend]属性は、interest のクラスを識別するために作成したものです)。

AutoExtend(a) ソース コードでこれらのクラスを検索し、(b) 次のような拡張機能を自動的に生成することから、ビルド プロセスを開始したいと考えています。

public partial class Foo {
    public static SomeType<int> Bar(Foo x) { ... };
    public static SomeOtherType<string> Baz(Foo x) { ... };
}

ソリューションをコンパイルする前に。

これを行う最善の方法を知っている人はいますか?Roslyn が最適だと思いますが、アドバイスをお待ちしています。AutoExtend理想的には、属性以外のユーザーの側で余分な「配管」を必要としないソリューションが欲しいです。

(誰かが興味を持っている場合に備えて、オーバーロードされた演算子を使用して C# クラスに関してドメイン固有言語を作成しています。上記により、DSL の使用が大幅に快適になります。)

4

1 に答える 1

5

コメントで示唆されているように、T4 ではかなり実現可能です。

ビルド時の変換に関しては、 .csprojファイルの<TransformOnBuild>プロパティを使用して実行できます。この質問、特に@Cheburekの回答を参照してください。詳細については、MSDNを参照してください。

次に、AutoExtend属性を持つクラスを見つけるには、リフレクションの代わりに EnvDTE を使用する必要があります。これは、既存のアセンブリが古くなっているためです。

何かのようなもの:

<#
// get a reference to the project of this t4 template
var project = VisualStudioHelper.CurrentProject;

// get all class items from the code model
var allClasses = VisualStudioHelper.GetAllCodeElementsOfType(project.CodeModel.CodeElements, EnvDTE.vsCMElement.vsCMElementClass, false);

// iterate all classes
foreach(EnvDTE.CodeClass codeClass in allClasses)
{
        // get all attributes this method is decorated with
        var allAttributes = VisualStudioHelper.GetAllCodeElementsOfType(codeClass.Attributes, vsCMElement.vsCMElementAttribute, false);
        // check if the SomeProject.AutoExtendedAttribute is present
        if (allAttributes.OfType<EnvDTE.CodeAttribute>()
                         .Any(att => att.FullName == "SomeProject.AutoExtended"))
        {
        #>
        // this class has been generated
        public partial class <#= codeClass.FullName #>
        {
          <#
          // now get all methods implemented by the class
          var allFunctions = VisualStudioHelper.GetAllCodeElementsOfType(codeClass.Members, EnvDTE.vsCMElement.vsCMElementFunction, false);
          foreach(EnvDTE.CodeFunction function in allFunctions)
          {
          #>
              public static <#= function.FullName #> etc...
          <#
          } 
          #>
        }
<#          
        }
    }
}
#>
于 2013-09-07T09:40:44.903 に答える