When a C# code fragment is compiled, all the code lines written are placed into a PREDEFINED METHOD of a PREDEFINED CLASS by the C# Source Code Mediator and a resultant compiled assembly represented as a byte array is generated.
Ever wondered what is the Name of this class, or the various other details like the access modifier, namespace within which this class is placed …. and the name of this predefined method where our C# Code is placed….
TEMPLATE PROCESSING/COMPILATION details:
Basically when you save a C# Code fragment, the C# Source Code Mediator’s ( CSharpSourceCodeMediator class ) COMPILEASSEMBLY method is called which compiles the whole fragment code and returns a BYTE ARRAY representing ( containing ) the final compiled assembly.
Below is the invocation sequence when you save the C# Code Fragment: ( read bottom up )
Tridion.ContentManager.Templating.Assembly.CSharpSourceCodeMediator.CompileAssembly(String) Tridion.ContentManager.Templating.Assembly.CSharpSourceCodeContentHandler.PerformValidateContent() Tridion.ContentManager.Templating.AbstractTemplateContentHandler.ValidateContent() Tridion.ContentManager.CommunicationManagement.Template.ProcessTemplateContent(String,String) Tridion.ContentManager.CommunicationManagement.Template.OnSaving(SaveEventArgs) Tridion.ContentManager.IdentifiableObject.Save(SaveEventArgs) Tridion.ContentManager.ContentManagement.VersionedItem.Save(Boolean) Tridion.ContentManager.ContentManagement.VersionedItem.Save() Tridion.ContentManager.BLFacade.ContentManagement.VersionedItemFacade.UpdateAndCheckIn(UserContext,String,Boolean,Boolean) XMLState.Save TemplateBuildingBlock.Save
The CSharpSourceCodeMediator processes the various directives( <%@Import, <%@Assembly, <%RunTemplate ) used, validates and compiles the TBB’s code (template code ) and generates error if any.
During the initial stages of processing, TBB’s code content is validated by firstly generating a predefined Class ( more better to say a sort of Class file .cs represented by a string ) representing the C# code fragment and then by Compiling the template code.
Yes, you read that right, the template code is compiled by intializing various CompilerParameters and a call to CompileAssemblyFromSource, this method takes the CompilerParameters as the first parameter and the second parameter is an array of source code strings to compile which is your actual template code only.
Let us now dig into the details of class and method(s) generated in the process.
PREDEFINED CLASS details:
- The compiled Class name ( i.e PREDEFINED CLASS ) given by Tridion is: CSharpSourceTemplate
- This class inherits the ITemplate interface
- The NAMESPACE wherein this compiled class is placed is: Tridion.Templating.CSharpTemplate
- This class has 3 variables available for Whole class: log, engine, package
So, Now you know why you can write package.PushItem(), engine.GetObject() in a C# TBB without even declaring any Engine , Package variables.
- All the above variables above are actually PRIVATE and cannot be access by any nested classes declared/defined, if any, within our C# code fragement
- For every <% RunTemplate %> directives declared, if any, in C# Code fragment, they are replaced by the RunTemplate method.
- For every import directive used <%@ Import %>, they are replaced by corresponding Using statements in the final compiled assembly.
- For every Assembly directive used: <%@ Assembly %> , they are added as it is to final compiled assembly.
- Any declarations done using : <%! %> , where we can declare functions, classes in a C# code fragment, gets added to the predefined class.
- Lastly , below using statements are added to the final assembly:
- using System
- using System.Text
- using System.Xml
- using Tridion.ContentManager
- using Tridion.ContentManager.CommunicationManagement
- using Tridion.ContentManager.ContentManagement
- using Tridion.ContentManager.Templating
PREDEFINED METHOD Details:
The PREDEFINED METHOD wherein all our code gets placed is : Transform .
- This method takes two parameters : Engine, Package
- All the Code , excluding those written inside construct <%! %> and the directives , is placed inside this Transform method.
Probably now you can guess that the C# Code Fragment is thus structured the way .Net assemblies are after completion of the compilation process.
Hope you enjoyed this post. Comments and Suggestions are welcome.
[ These details on compilation process was discovered when I faced issue while creating functions, classes in C# code fragment and thought to share these ]