I am attempting to write a custom template that derives from CodeTemplate and I am getting a null reference exception inside of the default constructor of the CodeTemplate class which is inside of the CodeSmith.Engine assembly. I have even looked at this assembly through reflector and can't see right off what would cause a null reference exception. Here is the code for the template I am writing, it is indeded to be a template which can be used to generate aspx pages along with their .cs code behind files.
First, I create a code template for the markup (.aspx) file:
public class MyMarkupTemplate : CodeTemplate {}
Then, I create a code template for the code behind (.cs) file:
public class MyCodeTemplate : CodeTemplate{}
Then I created a base Template class called WebPageTemplate which takes the two other templates as generic parameters:
public class WebPageTemplate<CodeType, MarkupType> : CodeTemplate
where CodeType : CodeTemplate, new()
where MarkupType : CodeTemplate, new()
{
private string codePath;
private string markupPath;
public string CodePath
{
get { return codePath; }
set { codePath = value; }
}
public string MarkupPath
{
get { return markupPath; }
set { markupPath = value; }
}
public override void Render(TextWriter writer)
{
writer.Write("Generating {0}...\n", CodePath);
CodeType code = Create<CodeType>();
code.RenderToFile(CodePath, true);
writer.Write("Generating {0}...\n", MarkupPath);
MarkupType markup = Create<MarkupType>();
markup.RenderToFile(MarkupPath, true);
}
}
This class simply overrides Render and attempts to render the two child templates to files.
Whenever I set up this scenario and try to run it from CodeSmith Studio, I get an error:
---------------------------
Template Error
---------------------------
Exception has been thrown by the target of an invocation.
So I tried running it via the API using the following Code:
CodeTemplateCompiler compiler = new CodeTemplateCompiler("MyTemplate.cst");
compiler.Compile();
if (compiler.Errors.Count == 0)
{
CodeTemplate template = compiler.CreateInstance();
template.Render(Console.Out);
}
else
{
for (int i = 0; i < compiler.Errors.Count; i++)
{
Console.WriteLine(compiler.Errors
.ToString());
}
}
and I get a null reference error in the CodeTemplate constructor. Here is the stack trace:
at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandle& ctor, Boolean& bNeedSecurityCheck)
at System.Activator.CreateInstance[T]()
at CodeSmith.Engine.CodeTemplate.Create[T](Boolean shareContextData)
at CodeSmith.Engine.CodeTemplate.Create[T]()
at TrendSource.CodeGeneration.WebPageTemplate`2.Render(TextWriter writer) in D:\Code\Library\TrendSource\TrendSource.CodeGeneration\WebPageTemplate.cs:line 42
at ClientSiteGenerator.MainForm.RunTemplate(String templatePath) in D:\Code\Apps\ClientSiteGenerator\ClientSiteGenerator\MainForm.cs:line 50
The final pieces are the .cst files. I am using blank templates which point to classes I have created which are basically:
<%@ CodeTemplate Language="C#" TargetLanguage="Text" Inherits="MyMasterTemplate" %>
<%@ Assembly Name="MyTemplates" %>
where MyMasterTemplate is the class that derives from WebPageTemplate.
This is the second time I have run into this error where a custom template is getting an ull reference exception in the default constructor of the base class (CodeTemplate). Has anybody else run into similiar problems? Am I going about this correctly?