1

これは私がしばらく解決するのに苦労してきた問題です。メソッド内のコードをコンパイル時にテンプレートから解析されたコードに置き換えるか(PostSharpが思い浮かびます)、動的プロキシを作成する方法(LinfuまたはCastle)が必要です。したがって、このようなソースコードが与えられます

[Template]

private string GetSomething()

{

var template = [%=Customer.Name%]

}

これにコンパイルする必要があります

private string GetSomething()

{

MemoryStream mStream = new MemoryStream();

            StreamWriter writer = new StreamWriter(mStream,System.Text.Encoding.UTF8);

writer.Write(@"" );

writer.Write(Customer.Name);

StreamReader sr = new StreamReader(mStream); 

writer.Flush();

mStream.Position = 0; 

return sr.ReadToEnd();

}

どのテクノロジーを使用するかは重要ではありません。PostSharpのImplementMethodAspectを試してみましたが、どこにも行きませんでした(経験不足のため)。Linfuフレームワークも調べました。誰かがこれを行うための他のアプローチや方法を提案できますか、私は本当に感謝します。私のプロジェクト全体はこれに依存しています。

仮定:

  1. コードはどのクラスにも表示できます。
  2. テンプレートコードには常に属性[テンプレート]の注釈が付けられます
  3. テンプレートメソッドは常に文字列を返します。

あるフォームから別のフォームへのコードの解析はすでに完了しています。今、私はそれを交換する方法が必要です。

「ビーファー」の例:

  [Test]
        public void can_parse_csharp_code_template3()
        {
            var template = @"<template> [%= GetUsing() %]
    namespace [%= GetModelNamespaceName(.metaPackage) %]
    {
    [%= .visibility.ToString().ToLower() %] class [%= .Name %] : INotifyPropertyChanged [%= If(.IsPersistent, "", PersistenObject"", """") %]
        {
            #region Constructors
            [%= ConstructorTemplate.Create(metaObject).GetParameterlessConstructorCode %]
            #endregion

            #region Attributes

            [%= From attribute In metaObject.attributes _
                Select (AttributeTemplate.Create(attribute).GetSourceCode) %]
            #endregion

            #region Relationships
            [%= From relationship As Relationship In metaObject.relationships _
                Select (RelationshipTemplateFactory.CreateFor(relationship).GetSourceCode()) %]
            #endregion

            #region Methods
            [%= From operation In metaObject.operations _
                Select (MethodTemplate.Create(operation).GetSourceCode) %]
            #endregion

            #region ""INotifyPropertyChanged""
            [%= GetOnPropertyChanged() %]
            #endregion
            }
        }</template>";

            Console.WriteLine(TemplateParser.GetParsedResult(template));

        }
4

2 に答える 2

2

T4(テキストテンプレート変換ツールキット)をご覧ください。

<#@ template language="C#v3.5" #>
<#@ assembly name="System.Core" #>
<#@ output extension=".cs" encoding="utf-8" #>

private string GetSomething()
{
    <# Generate("Customer.Name"); #>
}

<#+
private void Generate(string s)
{
    WriteLine(@"MemoryStream mStream = new MemoryStream();");
    // ...
}
#>
于 2010-04-07T13:09:25.350 に答える
0

C#を解析し、属性を選択し、そのコードを任意の方法で変換できるツールは、DMS Software Reengineering ToolkitとそのC#フロントエンドです。

DMSはファイルを解析し、完全な抽象構文木を構築し、テキスト内のポイントを拡張できるカスタム変換を記述できるようにします(T4などのほとんどのコードジェネレーターが実行します)。アプリケーションを構成するファイルのセット)と、生成したい他のコード。

あなたは、コードフラグメントを生成するためのメタ言語についていくつかの考えを持っているようです。

  From operation In metaObject.operations _ 
            Select (MethodTemplate.Create(operation).GetSourceCode) 

そのメタ言語AFAIKはC#ではありません。DMSを使用すると、メタ言語のパーサーを定義し、コードジェネレーターが構成要素に遭遇したときにメタ言語をツリーに処理できます。このようなツリーを介した小さなインタプリタを使用すると、金属ゲージのテキストをジェネレータアクションに変換して、目的のテキストを生成できます。

[私はDMSの背後にいるCTOです]。

于 2010-04-07T19:30:42.740 に答える