0

I want to pass in the default template parameters of a context controller T4 template from the CodeGenerator function for a new extension as such:

<#@ 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" #>

These are passed in through the scaffolding process from the Microsoft's MVC dll automatically but since I am overriding the scaffolding process with my own I want to pass them in myself in here:

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);
    }

Is there an easy way to do this?

2 Answers2

0

You can process a template by using the text templating service. Sample code, please refer to:

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

If you want to get the parameters from T4 template, you need to use ITextTemplatingEngineHost.ResolveParameterValue Method. Before use this method, you also need to Add hostspecific="true" attribute to template element.

Sample code, you code refer to:

Get argument value from TextTransform.exe into the template

Weiwei
  • 3,674
  • 1
  • 10
  • 13
  • Thanks Wendy, however what I want is to populate the ControllerName string, ControllerRootName, Namespace, AreaName, ContextTypeName, ModelTypeName.... etc with their respective values. – Justin Farrugia Sep 12 '17 at 12:24
  • In the sample code, it use ITextTemplatingSessionHost.CreateSession() method, which could pass value with key-value pairs. You could set the key name as ControllerName, ControllerRootName...etc and set the respective values for them. – Weiwei Sep 13 '17 at 02:34
  • I think I'm not explaining myself well. I know how to pass the values. All I want is to GET the values for ControllerName, ControllerRootName etc (entire list of parameters in my original post). – Justin Farrugia Sep 13 '17 at 04:58
  • Sorry for misunderstanding your questions. I have edit my answer. Please check whether it is helpful. If any questions, please feel free to let me know. – Weiwei Sep 13 '17 at 08:29
  • Hi Wendy, thanks for the answer. I upvoted your answer however it won't show for now as I do not have 15 reputations points. I did not mark it as the most helpful answer because I in the meantime I found a better answer myself. I will post below for you and other to see too. – Justin Farrugia Sep 13 '17 at 09:25
  • Thanks for your response. We are waiting for your better answer and thanks for sharing your answer. Please remember to mark your answer after sharing. – Weiwei Sep 14 '17 at 00:59
0
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;
}

I have since got much more deeper into the logic by calling the required classes for the values above to populate with the right values according to my solution.