我们的视觉工作室解决方案中嵌入了大量文本模板。
我正在使用这样一个简单的方法来加载它们:
public string getTemplate()
{
var assembly = Assembly.GetExecutingAssembly();
var templateName = "ResearchRequestTemplate.txt";
string result;
using (Stream stream = assembly.GetManifestResourceStream(templateName))
using (StreamReader reader = new StreamReader(stream))
{
result = reader.ReadToEnd();
}
return result;
}
所以我可以使用上面的方法加载文件,但是如何用我在代码中创建的变量替换文件中的模板变量?这甚至可能吗?也许我说这一切都错了......
ResearchRequestTemplate.txt:
Hello { FellowDisplayName }
You have requested access to the { ResearchProjectTitle } Project.
Please submit all paperwork and badge ID to { ResourceManagerDisplayName }
谢谢!
答案 0 :(得分:2)
您可以使用一系列string.Replace()
语句。
或者您可以修改模板并使用string.Format
:
Hello {0}
You have requested access to the {1} Project.
Please submit all paperwork and badge ID to {2}
阅读模板后,插入正确的值:
return string.Format(
result, fellowDisplayName, researchProjectTitle, resourceManagerDisplayName);
如果模板经常更改,这可能会有点容易出错,并且有人不小心确保模板中的编号与传入的参数顺序相匹配。
答案 1 :(得分:1)
选项1 - 使用运行时文本模板
作为一种优雅的解决方案,您可以使用Run-time Text Templates。将新的运行时文本模板项添加到项目中,并将文件命名为ResearchRequestTemplate.tt
,并将其放入其中:
<#@ template language="C#" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ parameter name="FellowDisplayName" type="System.String"#>
<#@ parameter name="ResearchProjectTitle" type="System.String"#>
<#@ parameter name="ResourceManagerDisplayName" type="System.String"#>
Hello <#= FellowDisplayName #>
You have requested access to the <#= ResearchProjectTitle #> Project.
Please submit all paperwork and badge ID to <#= ResourceManagerDisplayName #>
然后以这种方式使用它:
var template = new ResearchRequestTemplate();
template.Session = new Dictionary<string, object>();
template.Session["FellowDisplayName"]= value1;
template.Session["ResearchProjectTitle"]= value2;
template.Session["ResourceManagerDisplayName"] = value3;
template.Initialize();
var result = template.TransformText();
这是一种非常灵活的方式,你可以简单地扩展它,因为visual studio为你的模板生成一个C#类,例如你可以为它创建一个部分类,并在其中放入一些属性并简单地使用类型属性。 / p>
选项2 - 命名String.Format
您可以使用命名字符串格式方法:
以下是an implementation by James Newton:
public static class Extensions
{
public static string FormatWith(this string format, object source)
{
return FormatWith(format, null, source);
}
public static string FormatWith(this string format, IFormatProvider provider, object source)
{
if (format == null)
throw new ArgumentNullException("format");
Regex r = new Regex(@"(?<start>\{)+(?<property>[\w\.\[\]]+)(?<format>:[^}]+)?(?<end>\})+",
RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.IgnoreCase);
List<object> values = new List<object>();
string rewrittenFormat = r.Replace(format, delegate(Match m)
{
Group startGroup = m.Groups["start"];
Group propertyGroup = m.Groups["property"];
Group formatGroup = m.Groups["format"];
Group endGroup = m.Groups["end"];
values.Add((propertyGroup.Value == "0")
? source
: DataBinder.Eval(source, propertyGroup.Value));
return new string('{', startGroup.Captures.Count) + (values.Count - 1) + formatGroup.Value
+ new string('}', endGroup.Captures.Count);
});
return string.Format(provider, rewrittenFormat, values.ToArray());
}
}
用法:
"{CurrentTime} - {ProcessName}".FormatWith(
new { CurrentTime = DateTime.Now, ProcessName = p.ProcessName });
答案 2 :(得分:1)
您可以使用正则表达式使用简单的替换方案:
var replacements = new Dictionary<string, string>() {
{ "FellowDisplayName", "Mr Doe" },
{ "ResearchProjectTitle", "Frob the Baz" },
{ "ResourceManagerDisplayName", "Mrs Smith" },
};
string template = getTemplate();
string result = Regex.Replace(template, "\\{\\s*(.*?)\\s*\\}", m => {
string value;
if (replacements.TryGetValue(m.Groups[1].Value, out value))
{
return value;
}
else
{
// TODO: What should happen if we don't know what the template value is?
return string.Empty;
}
});
Console.WriteLine(result);