我有一组类似的类用于此,将模板化文本生成嵌入到软件中。
基本上,它的工作方式类似于旧式 ASP,您将 C# 代码包含在 <%...%> 块中,并且您可以使用 <%= expression %> 发出结果。
您可以将单个对象传递到模板代码中,当然可以是您喜欢的任何对象类型,或者只是一个参数数组。如果要执行自定义代码,也可以引用自己的程序集。
这是发出类的样子:
<%
var parameters = (string[])data;
var namespaceName = parameters[0];
var className = parameters[1];
%>
namespace <%= namespaceName %>
{
public class <%= className %>
{
}
}
你当然可以循环遍历事物:
<% foreach (var parameter in parameters) { %>
<%= parameter %>
<% } %>
并将代码放入 if 块等中。
类库在 CodePlex 上发布:
以及NuGet。
项目自带示例,下载源码或browse it online.
也可以在这里通过电子邮件回答问题,供其他人查看:
- 适合方法调用的所有类型的 C# 代码都可以在模板中编译。它运行正常的 C# 3.5 代码,这意味着没有人为限制。唯一要知道的是,任何包含要发出的模板代码的 if、while、for、foreach 等代码都必须使用大括号,您不能执行单行 if-then 类型块。有关方法调用限制,请参见下文。
-
data 参数对应于作为参数从您的应用程序传递给.Generate(x) 方法的任何内容,并且属于同一类型。如果您传入您在自己的类库中定义的对象,则需要添加对模板代码的引用才能正确访问它。 (<%@ reference your.class.library.dll %>)
- 如果你重用编译后的模板,它本质上只是一个类的方法调用,对
.Generate()的实际调用没有额外的开销。如果您不自己拨打.Compile(),第一次拨打.Generate() 将负责处理。另请注意,代码在单独的应用程序域中运行,因此与来回复制参数和结果相关的编组开销很小。但是,代码以正常的 JITted .NET 代码速度运行。
if-block 示例:
<% if (a == b) { %>
This will only be output if a==b.
<% } %>
对代码格式也没有人为限制,选择最适合你的样式:
<%
if (a == b)
{
%>
This will only be output if a==b.
<%
}
%>
请注意,模板的所有非代码部分几乎都将按原样输出,这意味着标签和类似%> 块也将被输出。
有一个限制,您编写的所有代码都必须适合单个方法调用。
让我解释一下。
模板引擎的工作方式是生成一个 .cs 文件并将其提供给 C# 编译器,这个 .cs 文件大致如下所示:
using directives
namespace SomeNamespace
{
public class SomeClass
{
public string Render(object data)
{
... all your code goes here
}
}
}
这意味着您不能定义新类、新方法、类级字段等。
但是,您可以使用匿名委托在内部创建函数。例如,如果您想要一种统一的日期格式:
Func<DateTime, string> date2str = delegate(DateTime dt)
{
return dt.ToString("G");
};
那么您可以在模板代码的其余部分中简单地使用它:
<%= date2str(DateTime.Now) %>
我的唯一要求是您不要将文件上传到网络上并声称您编写了代码,除非您可以随意使用它。
编辑 23.04.2011: 修复了 CodePlex 项目的链接。