这是我一段时间以来一直在努力解决的问题。我需要一种方法,要么在编译时用模板中的解析代码替换方法中的代码(想到 PostSharp),要么创建动态代理(Linfu 或 Castle)。所以给出这样的源代码
[Template]
private string GetSomething()
{
var template = [%=Customer.Name%]
}
我需要把它编译成这个
private string GetSomething()
{
MemoryStream mStream = new MemoryStream();
StreamWriter writer = new StreamWriter(mStream,System.Text.Encoding.UTF8);
writer.Write(@"" );
writer.Write(Customer.Name);
StreamReader sr = new StreamReader(mStream);
writer.Flush();
mStream.Position = 0;
return sr.ReadToEnd();
}
使用什么技术并不重要。我尝试使用 PostSharp 的 ImplementMethodAspect,但一无所获(由于缺乏经验)。我还研究了 Linfu 框架。有人可以建议一些其他方法或方法来做到这一点,我真的很感激。我的整个项目都依赖于此。
假设:
- 代码可以出现在任何类中。
- 模板代码将始终使用属性 [Template] 进行注释
- 模板方法将始终返回字符串。
将代码从一种形式解析到另一种形式已经完成。现在我只需要一种方法来替换它。
“牛肉”示例:
[Test]
public void can_parse_csharp_code_template3()
{
var template = @"<template> [%= GetUsing() %]
namespace [%= GetModelNamespaceName(.metaPackage) %]
{
[%= .visibility.ToString().ToLower() %] class [%= .Name %] : INotifyPropertyChanged [%= If(.IsPersistent, "", PersistenObject"", """") %]
{
#region Constructors
[%= ConstructorTemplate.Create(metaObject).GetParameterlessConstructorCode %]
#endregion
#region Attributes
[%= From attribute In metaObject.attributes _
Select (AttributeTemplate.Create(attribute).GetSourceCode) %]
#endregion
#region Relationships
[%= From relationship As Relationship In metaObject.relationships _
Select (RelationshipTemplateFactory.CreateFor(relationship).GetSourceCode()) %]
#endregion
#region Methods
[%= From operation In metaObject.operations _
Select (MethodTemplate.Create(operation).GetSourceCode) %]
#endregion
#region ""INotifyPropertyChanged""
[%= GetOnPropertyChanged() %]
#endregion
}
}</template>";
Console.WriteLine(TemplateParser.GetParsedResult(template));
}