У меня есть аналогичный набор классов, которые я использую для этого, встраивая генерацию шаблонного текста в программное обеспечение.
По сути, он работает как старый 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.
Проект поставляется с примерами, загрузите исходный код или просмотрите его в Интернете.
Чтобы ответить на вопросы по электронной почте также здесь, чтобы другие могли видеть:
- Все типы кода C#, подходящие для вызова метода, могут быть скомпилированы в шаблоне. Он запускает обычный код C# 3.5 со всем, что означает отсутствие искусственных ограничений. Единственное, что нужно знать, это то, что любой код if, while, for, foreach и т. д., который содержит код шаблона для генерации, должен использовать фигурные скобки, вы не можете сделать однострочный блок типа if-then. См. ниже ограничения вызовов методов.
- Параметр
data
соответствует тому, что было передано в качестве параметра методу .Generate(x)
из вашего приложения, и имеет тот же тип. Если вы передаете объект, который вы определили в своих собственных библиотеках классов, вам необходимо добавить ссылку на код шаблона, чтобы правильно получить к нему доступ. (<%@ reference your.class.library.dll %>
)
- Если вы повторно используете скомпилированный шаблон, по сути, это будет только вызов метода класса, никаких дополнительных накладных расходов на фактический вызов
.Generate()
не производится. Если вы не позвоните .Compile()
сами, об этом позаботится первый вызов .Generate()
. Также обратите внимание, что код выполняется в отдельном домене приложения, поэтому есть небольшие накладные расходы, связанные с копированием параметра и результата туда и обратно. Однако код выполняется с нормальной скоростью JIT-кода .NET.
Пример блока if:
<% 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.
person
Lasse V. Karlsen
schedule
21.02.2010