cool IT Team-Blog

Entity Framework: POCOs mit XML-Comments generieren

Das Generieren von POCO-Klassen aus dem Entity-Framework Modell klappt ja recht einfach.
Leider werden aber die Beschreibungen nicht als XML-Comments übernommen.

Aber es gibt eine Lösung: einfach die T4-Templates erweitern...

Zum Erstellen der POCO-Klassen und der Context-Klasse (enthält den Datenbank-Zugriff) werden 2 T4-Templates benutzt: z.B. DataModel.tt und DataModel.Context.tt
Durch Ändern dieser Dateien kann die Code-Generierung verändert werden.

Das Extrahieren der Dokumentation aus dem EDMX-Modell ist sehr einfach, leider aber nicht gut dokumentiert. Jedes MetaitemData-Objekt (z.B. der EntityContairner, jedes EntitySet oder jeder EntityType) enthält ein optionales Property 'Documentation'. Hier sind 'Summary' und 'LongDescription' aus dem Modell abgelegt.

folgende Punkte sind zu beachten:
  1. ist keine Dokumentation im Modell hinterlegt, ist .Documentation null
  2. Zeilenumbrüche müssen beim Erstellen der XML-Kommentare entsprechend um den Komentar-Prefix ergänzt werden
  3. die Dokumentation muss XML-Encoded werden (z.B. &, <, >)

Als C#-Beispiel wurden die T4-Templates um folgenden Code ergänzt:


#region XML-Comments
  private const string XMLCOMMENT_START = "/// ";
  
  private static string XmlEntityize(string text)
  {
    if (string.IsNullOrEmpty(text))
    {
      return string.Empty;
    }
  
    text = text.Replace("&","&amp;");
    text = text.Replace("<","&lt;").Replace(">","&gt;");
    string id = Guid.NewGuid().ToString();
    text = text.Replace(Environment.NewLine, id);
    text = text.Replace("\r""&#xD;").Replace("\n","&#xA;");
    text = text.Replace(id, Environment.NewLine);
    return text.Replace("\'","&apos;").Replace("\"","&quot;");
  }
  private static string PrefixLinesOfMultilineComment(string prefix, string comment)
  {
    return comment.Replace(Environment.NewLine, Environment.NewLine + prefix);
  }
  
  public static string SummaryCommentElement(MetadataItem item, string defaultComment)
  {
    var comment = ((item.Documentation != null) && !string.IsNullOrWhiteSpace(item.Documentation.Summary))
                 ? item.Documentation.Summary : defaultComment;
    if (string.IsNullOrWhiteSpace(comment))
      return string.Empty;
  
    comment = PrefixLinesOfMultilineComment(XMLCOMMENT_START, XmlEntityize(comment));
    return string.Format((comment.Contains(Environment.NewLine)
                  ? "{0}<summary>\n{0}{1}\n{0}</summary>" : "{0}<summary>{1}</summary>"),
                         XMLCOMMENT_START, comment);
  }
 
  public static string LongDescriptionCommentElement(MetadataItem item, int indentLevel)
  {
   var comment = ((item.Documentation != null) &&
                   !string.IsNullOrWhiteSpace(item.Documentation.LongDescription))
                  ? item.Documentation.LongDescription : string.Empty;
    if (string.IsNullOrWhiteSpace(comment))
      return string.Empty;
    
    comment = PrefixLinesOfMultilineComment(XMLCOMMENT_START, XmlEntityize(comment));
    return string.Format((comment.Contains(Environment.NewLine)
                  ? "\n{0}<LongDescription>\n{0}{1}\n{0}</LongDescription>"
                         : "\n{0}<LongDescription>{1}</LongDescription>"),
                         XMLCOMMENT_START, comment);
  }
 
  public static string ParameterComments(IEnumerable<Tuple<stringstring>> parameters, int indentLevel)
  {
    System.Text.StringBuilder builder = new System.Text.StringBuilder();
    foreach (Tuple<stringstring> parameter in parameters)
    {
      builder.AppendLine();
      builder.Append(CodeRegion.GetIndent(indentLevel));
      builder.Append(XMLCOMMENT_START);
      builder.Append(String.Format(CultureInfo.InvariantCulture,
                           " <param name=\"{0}\">{1}</param>", parameter.Item1, parameter.Item2));
    }
    return builder.ToString();
}
#endregion // XML-Comments

Verwendet wird das dann z.B. so:

<#=SummaryCommentElement(entity, "Generated Entity-Class.")#> <#=LongDescriptionCommentElement(entity, region.CurrentIndentLevel)#>

Ist doch cool, oder?
Verfasst: 12.01.2012 10:16:30 von Georg Reh
Tags: Entity-Framework, POCO, T4-Templates

1


Kommentare
Für diesen Blogbeitrag liegen zurzeit keine Kommentare vor.
Einen Kommentar schreiben



 Security code