-
Notifications
You must be signed in to change notification settings - Fork 3
Wrapped Mediator
The wrapped mediator wraps around the existing Tridion CSharpSourceCodeMediator and redirects assembly libraries being loaded during templating to the configured debug libraries.
In Tridion, templates hosted in compiled assemblies are executed using the following code:
/* This template was generated through the Tridion Assembly Template Upload */
<%RunTemplate Template="tcm:101-12103-2048" Class="Company.Tridion.Templating.Template"%>
Subsequently the CSharpSourceCodeMediator reads this C# fragment, includes it in a dynamically generated class and compiles this into a temporary assembly (This is why Tridion publisher needs to be restarted when many templates are updated, as dynamic assemblies cannot be unloaded from the application domain).
This assembly is then loaded and it loads the final assembly from the target uri which contains the requested class.
Note: Tridion will only pass the ClassName if the mediator configured for the type application/x-tcm-assembly is the exact class Tridion.ContentManager.Templating.Assembly.AssemblyMediator
Because of this the AssemblyMediator cannot be wrapped as the !ClassName would not be passed on from the RunTemplate instruction.
Once the wrapped mediator is executing it will verify if the template which is executing is a RunTemplate tcm upload generated TBB as displayed above:
String templateCode = template.Content;
if (templateCode.Contains(RUNTEMPLATE))
{
// Call the original ProcessRunTemplateCalls to process any "RunTemplate" executions
ProcessRunTemplateCalls(ref templateCode);
// Add our own assembly as an additional using reference for compilation
templateCode = String.Format("<%@Import Namespace=\"{0}\"%>\n<%@Assembly Name=\"{1}\"%>\n", this.GetType().Namespace, this.GetType().Assembly.FullName) + templateCode;
// Wrap any RunTemplate() calls through our RunTemplateWrapper()
template.Content = templateCode.Replace("RunTemplate(", this.GetType().Name + ".RunTemplateWrapper(");
}
If a RunTemplate TBB has been located, the original CSharpSourceCodeMediator.ProcessRunTemplateCalls is called transform the RunTemplate class into a C# procedure call. Additionally our current library is added as an additional dependency, which allows the wrapped mediator to replace the!RunTemplate() call with the RunTemplateWrapper().
After this the CSharpSourceCodeMediator will create the dynamic assembly as normal and execute it.
During the C# fragment execution the mediator will be called in order to execute the RunTemplate call:
/// <summary>
/// Wraps around the original RunTemplate in order to load debug classes when required
/// </summary>
/// <param name="engine"><see cref="T:Tridion.ContentManager.Templating.Engine" /></param>
/// <param name="package"><see cref="T:Tridion.ContentManager.Templating.Package"/></param>
/// <param name="templateUri"><see cref="T:Tridion.ContentManager.CommunicationManagement.Template"/></param>
/// <param name="className">Class to execute</param>
/// <remarks>
/// The wrapper tries to load the specified class from available assemblies in the following order:
/// 1) Assemblies configured as debug assemblies in the application configuration
/// 2) Assemblies loaded in the application domain
/// 3) Assembly with the same name as the template present in the application directory
/// 4) Assembly stored in the Tridion database (default behavior of Tridion)
/// </remarks>
public static void RunTemplateWrapper(Engine engine, Package package, String templateUri, String className)
{
ITemplate template = null;
// Try and obtain the requested template from the loaded debug assemblies
template = GetTemplate(mDebugAssemblies, className);
...
The RunTemplate wrapper will evaluate available assemblies in order and verify if any of them contain the template referenced by the RunTemplate class.
- Assemblies configured as debug assemblies in the TcmDebugger configuration
- Assemblies already loaded in the application domain
- Assembly with the same name as the uploaded assembly in Tridion present in the TcmDebugger directory
- Assembly as present in the assembly TBB (default behaviour of CSharpSourceCodeMediator).
This allows TcmDebugger to execute the template code locally using the latest version of the code instead of the assembly uploaded in the Tridion CMS.