[cnblogs] 在UWP中使用T4的注意事项
在UWP中尝试使用T4的朋友们可能会注意到,VS设计器默认生成的运行时T4无法通过编译,因为他使用了一些不支持UWP的API,解决方案也很简单,知道将其复制出来,修正不兼容的部分,指定inherits参数为新的基类即可,这里提供一个简单的版本,应该还可以优化
public class FormatterBase
{
private bool _endsWithNewline;
private StringBuilder _generationEnvironmentField;
private List<int> _indentLengthsField;
protected StringBuilder GenerationEnvironment
{
get
{
if ((_generationEnvironmentField == null))
{
_generationEnvironmentField = new StringBuilder();
}
return _generationEnvironmentField;
}
set { _generationEnvironmentField = value; }
}
/// <summary>
/// A list of the lengths of each indent that was added with PushIndent
/// </summary>
private List<int> IndentLengths
{
get
{
if ((_indentLengthsField == null))
{
_indentLengthsField = new List<int>();
}
return _indentLengthsField;
}
}
/// <summary>
/// Gets the current indent we use when adding lines to the output
/// </summary>
public string CurrentIndent { get; private set; } = "";
/// <summary>
/// Current transformation session
/// </summary>
public virtual IDictionary<string, object> Session { get; set; }
public virtual string TransformText()
{
GenerationEnvironment.Clear();
Render();
return string.Empty;
}
protected virtual void Render()
{
}
#region Transform-time helpers
/// <summary>
/// Write text directly into the generated output
/// </summary>
public void Write(string textToAppend)
{
if (string.IsNullOrEmpty(textToAppend))
{
return;
}
// If we're starting off, or if the previous text ended with a newline,
// we have to append the current indent first.
if (((GenerationEnvironment.Length == 0)
|| _endsWithNewline))
{
GenerationEnvironment.Append(CurrentIndent);
_endsWithNewline = false;
}
// Check if the current text ends with a newline
if (textToAppend.EndsWith(Environment.NewLine, StringComparison.CurrentCulture))
{
_endsWithNewline = true;
}
// This is an optimization. If the current indent is "", then we don't have to do any
// of the more complex stuff further down.
if ((CurrentIndent.Length == 0))
{
GenerationEnvironment.Append(textToAppend);
return;
}
// Everywhere there is a newline in the text, add an indent after it
textToAppend = textToAppend.Replace(Environment.NewLine, (Environment.NewLine + CurrentIndent));
// If the text ends with a newline, then we should strip off the indent added at the very end
// because the appropriate indent will be added when the next time Write() is called
if (_endsWithNewline)
{
GenerationEnvironment.Append(textToAppend, 0, (textToAppend.Length - CurrentIndent.Length));
}
else
{
GenerationEnvironment.Append(textToAppend);
}
}
/// <summary>
/// Write text directly into the generated output
/// </summary>
public void WriteLine(string textToAppend)
{
Write(textToAppend);
GenerationEnvironment.AppendLine();
_endsWithNewline = true;
}
/// <summary>
/// Write formatted text directly into the generated output
/// </summary>
public void Write(string format, params object[] args)
{
Write(string.Format(CultureInfo.CurrentCulture, format, args));
}
/// <summary>
/// Write formatted text directly into the generated output
/// </summary>
public void WriteLine(string format, params object[] args)
{
WriteLine(string.Format(CultureInfo.CurrentCulture, format, args));
}
/// <summary>
/// Increase the indent
/// </summary>
public void PushIndent(string indent)
{
if ((indent == null))
{
throw new ArgumentNullException(nameof(indent));
}
CurrentIndent = (CurrentIndent + indent);
IndentLengths.Add(indent.Length);
}
/// <summary>
/// Remove the last indent that was added with PushIndent
/// </summary>
public string PopIndent()
{
var returnValue = "";
if ((IndentLengths.Count > 0))
{
var indentLength = IndentLengths[(IndentLengths.Count - 1)];
IndentLengths.RemoveAt((IndentLengths.Count - 1));
if ((indentLength > 0))
{
returnValue = CurrentIndent.Substring((CurrentIndent.Length - indentLength));
CurrentIndent = CurrentIndent.Remove((CurrentIndent.Length - indentLength));
}
}
return returnValue;
}
/// <summary>
/// Remove any indentation
/// </summary>
public void ClearIndent()
{
IndentLengths.Clear();
CurrentIndent = "";
}
#endregion
#region ToString Helpers
/// <summary>
/// Utility class to produce culture-oriented representation of an object as a string.
/// </summary>
public class ToStringInstanceHelper
{
private IFormatProvider _formatProviderField = CultureInfo.InvariantCulture;
/// <summary>
/// Gets or sets format provider to be used by ToStringWithCulture method.
/// </summary>
public IFormatProvider FormatProvider
{
get { return _formatProviderField; }
set
{
if ((value != null))
{
_formatProviderField = value;
}
}
}
/// <summary>
/// This is called from the compile/run appdomain to convert objects within an expression block to a string
/// </summary>
public string ToStringWithCulture(object objectToConvert)
{
if ((objectToConvert == null))
{
throw new ArgumentNullException(nameof(objectToConvert));
}
var t = objectToConvert.GetType();
var method = t.GetMethod("ToString", new[]
{
typeof (IFormatProvider)
});
//if ((method == null))
//{
return objectToConvert.ToString();
//}
//return ((string) (method.Invoke(objectToConvert, new object[]
//{
// _formatProviderField
//})));
}
}
/// <summary>
/// Helper to produce culture-oriented representation of an object as a string
/// </summary>
public ToStringInstanceHelper ToStringHelper { get; } = new ToStringInstanceHelper();
#endregion
}