Pergunta

Este é um problema que tenho lutado para resolver por um tempo. Preciso de uma maneira de substituir o código no método por um código analisado do modelo no horário de compilação (PostSharp vem à mente) ou para criar um proxy dinâmico (Linfu ou Castle). Então, dado um código -fonte como este

[Template]

private string GetSomething()

{

var template = [%=Customer.Name%]

}

Eu preciso que seja compilado nisso

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();

}

Não é importante o que a tecnologia é usada. Eu tentei com o implementMethodaspecto do PostSharp, mas não cheguei a lugar algum (devido à falta de experiência com ele). Eu também olhei para a estrutura de Linfu. Alguém pode sugerir alguma outra abordagem ou maneira de fazer isso, eu realmente apreciaria. Todo o meu projeto depende disso.

Suposições:

  1. O código pode aparecer em qualquer classe.
  2. O código do modelo sempre será anotado com atributo [modelo
  3. O método do modelo sempre retornará a string.

A análise do código de um formulário para outro já está concluída. Agora eu só preciso de uma maneira de substituí -lo.

Exemplo de "Beefer":

  [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));

        }
Foi útil?

Solução

Dê uma olhada em T4 (kit de ferramentas de transformação do modelo de texto).

<#@ 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();");
    // ...
}
#>

Outras dicas

Uma ferramenta que pode analisar C#, escolher atributos e transformar esse código da maneira que desejar, é o DMS Software Reengeneering Toolkit e os seus C# front -end.

O DMS analisa seus arquivos, cria árvores de sintaxe de abstacto completas e permite escrever transformações personalizadas que possam expandir um ponto no texto (o que a maioria dos geradores de código como T4 faz) ou, mais importante, substitua qualquer construto (local e/ou distribuído através do definir de arquivos que compõem o aplicativo) com qualquer outro código que você possa gerar.

Você parece ter uma idéia sobre a metalinguagem para produzir fragmentos de código, por exemplo,

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

Esse metalanguage afaik não é C#. Com o DMS, você pode definir um analisador para a metalanguage e processar a meta Langauge em árvores, à medida que o gerador de código encontra as construções. Com um pequeno intérprete sobre essas árvores, você pode converter o texto do MetalNguage em ações geradoras que produzem o texto de interesse.

Eu sou o CTO atrás do DMS].

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top