16.07.2010
00:25

Parametrisierte Text Templates und System.Runtime.Serialization.SerializationException

Zurzeit beschäftige ich mich mit den T4 Templates. Ein sporadisches Problem ala Murphy trat bei parametrisierten Vorlagen auf. Wenn ich diese innerhalb einer anderen Textvorlage aufgerufen habe und einen Parameter mit einem benutzerdefinierten Objekt übergeben wollte begrüsste mich die Fehlermeldung:

Auszug Fehlermeldung
Error        Running transformation:
System.Runtime.Serialization.SerializationException: Unable to find
assembly 'UmlHelper, Version=1.0.0.0, Culture=neutral,
PublicKeyToken=null'.

Server stack trace:
   at
System.Runtime.Serialization.Formatters.Binary.BinaryAssemblyInfo.GetAssembly()
   at
System.Runtime.Serialization.Formatters.Binary.ObjectReader.GetType(BinaryAssemblyInfo
assemblyInfo, String name)
   at
System.Runtime.Serialization.Formatters.Binary.ObjectMap..ctor(String
objectName, String[] memberNames, BinaryTypeEnum[] binaryTypeEnumA,
Object[] typeInformationA, Int32[] memberAssemIds, ObjectReader
objectReader, Int32 objectId, BinaryAssemblyInfo assemblyInfo,
SizedArray assemIdToAssemblyTable)
   at
System.Runtime.Serialization.Formatters.Binary.__BinaryParser.ReadObjectWithMapTyped(BinaryObjectWithMapTyped
record)
   at
System.Runtime.Serialization.Formatters.Binary.__BinaryParser.ReadObjectWithMapTyped(BinaryHeaderEnum
binaryHeaderEnum)
   at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.Run()
   at
System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler
handler, __BinaryParser serParser, Boolean fCheck, Boolean
isCrossAppDomain, IMethodCallMessage methodCallMessage)
   at
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream
serializationStream, HeaderHandler handler, Boolean fCheck, Boolean
isCrossAppDomain, IMethodCallMessage methodCallMessage)
   at
System.Runtime.Remoting.Channels.CrossAppDomainSerializer.DeserializeObject(MemoryStream
stm)
   at
System.Runtime.Remoting.Messaging.SmuggledMethodCallMessage.FixupForNewAppDomain()
   at
System.Runtime.Remoting.Channels.CrossAppDomainSink.DoDispatch(Byte[]
reqStmBuff, SmuggledMethodCallMessage smuggledMcm,
SmuggledMethodReturnMessage& smuggledMrm)
   at
System.Runtime.Remoting.Channels.CrossAppDomainSink.DoTransitionDispatchCallback(Object[]
args)

Exception rethrown at [0]:
   at
System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage
reqMsg, IMessage retMsg)
   at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData&
msgData, Int32 type)
   at
Microsoft.VisualStudio.TextTemplating.ITextTemplatingSessionHost.set_Session(ITextTemplatingSession
value)
   at
Microsoft.VisualStudio.TextTemplatingBD1EC50CBA912372FF5EDDFDC3DFE64D.GeneratedTextTransformation.GetGeneratedOutputWithTemplate(String
templateName, ObjectData element)
   at
Microsoft.VisualStudio.TextTemplatingBD1EC50CBA912372FF5EDDFDC3DFE64D.GeneratedTextTransformation.TransformText()
   at
Microsoft.VisualStudio.TextTemplating.TransformationRunner.RunTransformation(TemplateProcessingSession
session, String source, ITextTemplatingEngineHost host, String&
result)

Der Aufruf der Parameter-Vorlage erfolgte in der Hauptvorlage nach folgenden Muster:

C# Class Feature Block 
private string GetGeneratedOutputWithTemplate(string templateName, TestUML.ObjectData element) 
{		
  string templateFile = this.Host.ResolvePath(templateName);
  string templateContent = File.ReadAllText(templateFile);

  TextTemplatingSession session = new TextTemplatingSession();
  session["Element"] = element;

  // requires host specific true
  var sessionHost = (ITextTemplatingSessionHost) this.Host;
  sessionHost.Session = session;

  Engine engine = new Engine();
  string generatedContent = engine.ProcessTemplate(templateContent, this.Host);

  return generatedContent;
} 

In der Session wurde ein Objekt übergeben, das in der aktuellen Vorlage erstellt wurde. Im Template mit dem Parameter soll dann nur noch die Ausgabe aufbereitet werden.

Die parametrisierte Vorlage ist so weniger komplex und enthält nur die Ausgabelogik:

Parametrisierte T4 Vorlage 
<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ output extension=".cs" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ parameter name="Element" type="TestUML.ObjectData" #>
/// 
namespace <#= Element.Namespace #>
{
  using System;
	
  public partial class <#=  Element.ObjectName #>
  {
<# 
     foreach (var item in Element.ObjectAttributes) {
#>	
      public <#= item.TypeName #> <#= item.Name #> { get; set; }
<# 
      }
#>
      }
}

Wie kam nun dieser Fehler zustande und warum? Der Code wird innerhalb einer AppDomain ausgeführt. So war es sporadisch möglich, dass das Helper-Objekt nicht gefunden werden konnte, da die Templates bzw. die Dll-Datei nicht innerhalb der gleichen AppDomain liefen. Lösen konnte ich das Problem, indem ich der Hilfsklasse die Parent-Klasse MarshalByRefObject spendierte. Diese ermöglicht den Zugriff auf das Objekt über die AppDomain-Grenzen hinaus.

C# (Hilfsobjekt)
[Serializable]
public class ObjectData : MarshalByRefObject
{
    public string Namespace { get; set; }
    public string ObjectName { get; set; }
    public List ObjectAttributes { get; set; }
}


Mal sehen, ob die sporadische Fehlermeldung nun auch definitiv beseitigt ist.

  •  
  • 0 Kommentar(e)
  •  

Mein Kommentar

Über jeden weiteren Kommentar in diesem Post benachrichtigen.

Zurück

Translate this page

Kategorien

  • [-].NET Development (215)
  • [-]Datenbank (26)
  • HTML (1)
  • Konfiguration (12)
  • Mind Map (10)
  • Off-topic (9)
  • Open Source (3)
  • Qualität (7)
  • Sharepoint (6)
  • Sicherheit (2)

Archiv

Social Bookmarking

Bookmark bei: Mr. Wong Bookmark bei: Webnews Bookmark bei: Icio Bookmark bei: Oneview Bookmark bei: Linkarena Bookmark bei: Favoriten Bookmark bei: Seekxl Bookmark bei: Favit Bookmark bei: Social Bookmarking Tool Bookmark bei: Power Oldie Bookmark bei: Bookmarks.cc Bookmark bei: Newskick Bookmark bei: Newsider Bookmark bei: Linksilo Bookmark bei: Readster Bookmark bei: Folkd Bookmark bei: Yigg Bookmark bei: Digg Bookmark bei: Del.icio.us Bookmark bei: Reddit Bookmark bei: Simpy Bookmark bei: StumbleUpon Bookmark bei: Slashdot Bookmark bei: Netscape Bookmark bei: Furl Bookmark bei: Yahoo Bookmark bei: Spurl Bookmark bei: Google Bookmark bei: Blinklist Bookmark bei: Blogmarks Bookmark bei: Diigo Bookmark bei: Technorati Bookmark bei: Newsvine Bookmark bei: Blinkbits Bookmark bei: Ma.Gnolia Bookmark bei: Smarking Bookmark bei: Netvouz Information