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;
}
从那以后,我通过为上述值调用所需的 类 以根据我的解决方案填充正确的值,从而更深入地了解了逻辑。
我想从 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;
}
从那以后,我通过为上述值调用所需的 类 以根据我的解决方案填充正确的值,从而更深入地了解了逻辑。