T4 默认模板参数

T4 default template parameters

我想从 CodeGenerator 函数中为新扩展传递上下文控制器 T4 模板的默认模板参数:

<#@ parameter type="System.String" name="ControllerName" #>
<#@ parameter type="System.String" name="ControllerRootName" #>
<#@ parameter type="System.String" name="Namespace" #>
<#@ parameter type="System.String" name="AreaName" #>
<#@ parameter type="System.String" name="ContextTypeName" #>
<#@ parameter type="System.String" name="ModelTypeName" #>
<#@ parameter type="System.String" name="ModelVariable" #>
<#@ parameter type="Microsoft.AspNet.Scaffolding.Core.Metadata.ModelMetadata" name="ModelMetadata" #>
<#@ parameter type="System.String" name="EntitySetVariable" #>
<#@ parameter type="System.Boolean" name="UseAsync" #>
<#@ parameter type="System.Boolean" name="IsOverpostingProtectionRequired" #>
<#@ parameter type="System.String" name="BindAttributeIncludeText" #>
<#@ parameter type="System.String" name ="OverpostingWarningMessage" #>
<#@ parameter type="System.Collections.Generic.HashSet<System.String>" name="RequiredNamespaces" #>

这些是通过脚手架过程自动从 Microsoft 的 MVC dll 传入的,但是由于我用自己的脚手架过程覆盖了脚手架过程,所以我想在这里自己传递它们:

public override void GenerateCode()
    {
        // Get the selected code type
        var codeType = _viewModel.SelectedModelType.CodeType;

        // Add the custom scaffolding item from T4 template.
        this.AddFileFromTemplate(Context.ActiveProject,
            "MVCBootstrapServerTable",
            "CustomTextTemplate",
            GetParameters(),           //to provide the parameters here!
            skipIfExists: false);
    }

有没有简单的方法来做到这一点?

您可以使用文本模板服务处理模板。示例代码,请参考:

https://msdn.microsoft.com/en-us/library/gg586944.aspx#Anchor_1

如果要获取T4模板的参数,需要使用ITextTemplatingEngineHost.ResolveParameterValue方法。使用此方法之前,您还需要将 hostspecific="true" 属性添加到模板元素。

示例代码,您的代码参考:

Get argument value from TextTransform.exe into the template

protected virtual IDictionary<string, object> AddTemplateParameters(CodeType dbContextType, ModelMetadata modelMetadata)
{
  if (dbContextType == null)
    throw new ArgumentNullException(nameof (dbContextType));
  if (modelMetadata == null)
    throw new ArgumentNullException(nameof (modelMetadata));
  if (string.IsNullOrEmpty(this.Model.ControllerName))
    throw new InvalidOperationException(Microsoft.AspNet.Scaffolding.Mvc.Properties.Resources.InvalidControllerName);
  IDictionary<string, object> dictionary = (IDictionary<string, object>) new Dictionary<string, object>((IEqualityComparer<string>) StringComparer.OrdinalIgnoreCase);
  CodeType codeType = this.Model.ModelType.CodeType;
  dictionary.Add("ModelMetadata", (object) modelMetadata);
  string str = codeType.Namespace != null ? codeType.Namespace.FullName : string.Empty;
  dictionary.Add("ModelTypeNamespace", (object) str);
  HashSet<string> requiredNamespaces = this.GetRequiredNamespaces((IEnumerable<CodeType>) new List<CodeType>()
  {
    codeType,
    dbContextType
  });
  dictionary.Add("RequiredNamespaces", (object) requiredNamespaces);
  dictionary.Add("ModelTypeName", (object) codeType.Name);
  dictionary.Add("ContextTypeName", (object) dbContextType.Name);
  dictionary.Add("UseAsync", (object) this.Model.IsAsyncSelected);
  string escapedIdentifier = ValidationUtil.GenerateCodeDomProvider(this.Model.ActiveProject.GetCodeLanguage()).CreateEscapedIdentifier(this.Model.ModelType.ShortTypeName.ToLowerInvariantFirstChar());
  dictionary.Add("ModelVariable", (object) escapedIdentifier);
  dictionary.Add("EntitySetVariable", (object) modelMetadata.EntitySetName.ToLowerInvariantFirstChar());
  if (this.Model.IsViewGenerationSupported)
  {
    bool flag = OverpostingProtection.IsOverpostingProtectionRequired(codeType);
    dictionary.Add("IsOverpostingProtectionRequired", (object) flag);
    if (flag)
    {
      dictionary.Add("OverpostingWarningMessage", (object) OverpostingProtection.WarningMessage);
      dictionary.Add("BindAttributeIncludeText", (object) OverpostingProtection.GetBindAttributeIncludeText(modelMetadata));
    }
  }
  return dictionary;
}

从那以后,我通过为上述值调用所需的 类 以根据我的解决方案填充正确的值,从而更深入地了解了逻辑。