70 lines
3.6 KiB
PowerShell
70 lines
3.6 KiB
PowerShell
[T4Scaffolding.Scaffolder(Description = "Creates an action method, view model, and view")][CmdletBinding()]
|
|
param(
|
|
[parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)][string]$Controller,
|
|
[parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)][string]$Action,
|
|
[string]$ViewModel,
|
|
[switch]$WithViewModel,
|
|
[switch]$Post,
|
|
[string]$Project,
|
|
[string]$CodeLanguage,
|
|
[string[]]$TemplateFolders,
|
|
[switch]$NoChildItems = $false,
|
|
[switch]$Force = $false
|
|
)
|
|
|
|
$Controller = [System.Text.RegularExpressions.Regex]::Replace($Controller, "Controller$", "", [System.Text.RegularExpressions.RegexOptions]::IgnoreCase)
|
|
$foundControllerType = Get-ProjectType ($Controller + "Controller") -Project $Project
|
|
if (!$foundControllerType) { return }
|
|
|
|
# Work out what area the controller is in, since we need to put viewmodels/views in the same area
|
|
$areaMatch = [System.Text.RegularExpressions.Regex]::Match($foundControllerType.Namespace.FullName, "^(.*)\.Areas\.(.*)\.Controllers")
|
|
$areaName = if ($areaMatch.Success) { $areaMatch.Groups[2].Value }
|
|
|
|
if ($ViewModel -or $WithViewModel) {
|
|
# First try to find an existing view model class
|
|
if ($ViewModel) {
|
|
$foundViewModel = Get-ProjectType $ViewModel -Project $Project -ErrorAction SilentlyContinue
|
|
}
|
|
# If not found or specified, try to create a new one
|
|
if (!$foundViewModel) {
|
|
if (!$ViewModel) { $ViewModel = $Action + "ViewModel" }
|
|
if ($ViewModel.Contains(".")) { $ViewModel = $ViewModel.Substring($ViewModel.LastIndexOf(".") + 1) }
|
|
|
|
# Decide where to put the new view model class
|
|
$defaultNamespace = (Get-Project $Project).Properties.Item("DefaultNamespace").Value
|
|
$viewModelNamespace = if ($areaName) { "$defaultNamespace.Areas.$areaName.Models" } else { "$defaultNamespace.Models" }
|
|
$viewModelOutputPath = if ($areaName) { "Areas\$areaName\Models\$ViewModel" } else { "Models\$ViewModel" }
|
|
|
|
# Actually create the view model class
|
|
Add-ProjectItemViaTemplate $viewModelOutputPath -Template ViewModel -Model @{ ClassName = $ViewModel; Namespace = $viewModelNamespace; DefaultNamespace = $defaultNamespace; } `
|
|
-SuccessMessage "Added view model class at {0}" -TemplateFolders $TemplateFolders -Project $Project -CodeLanguage $CodeLanguage -Force:$Force
|
|
$foundViewModel = Get-ProjectType ($viewModelNamespace + "." + $ViewModel) -Project $Project
|
|
}
|
|
|
|
# Also import the view model namespace if not already imported
|
|
$existingImport = $foundControllerType.ProjectItem.FileCodeModel.CodeElements | ?{ ($_.Kind -eq 35) -and ($_.Namespace -eq $foundViewModel.Namespace.FullName) }
|
|
if (!$existingImport) {
|
|
$foundControllerType.ProjectItem.FileCodeModel.AddImport($foundViewModel.Namespace.FullName) | Out-Null
|
|
}
|
|
}
|
|
|
|
# Add the action method
|
|
$template = if ($Post) { "ActionPost" } else { "Action" }
|
|
$actionMethodName = if ($Post) { $Action + "Post" } else { $Action }
|
|
Add-ClassMemberViaTemplate -Name $actionMethodName -CodeClass $foundControllerType -Template $template `
|
|
-Model @{ Action = $Action; ViewModel = [MarshalByRefObject]$foundViewModel } `
|
|
-SuccessMessage "Added action method $Action to $($foundControllerType.Name)" `
|
|
-TemplateFolders $TemplateFolders -Project $Project -CodeLanguage $CodeLanguage -Force:$Force
|
|
|
|
# Finally, create a view
|
|
$viewModelType = if ($foundViewModel) { $foundViewModel.FullName } else { $null }
|
|
if (!$NoChildItems) {
|
|
Scaffold View $Controller $Action -ModelType $viewModelType -Area $areaName -Force:$Force
|
|
}
|
|
|
|
# Return info about what we did in case other scaffolders wish to consume it
|
|
return @{
|
|
Controller = $foundControllerType;
|
|
ActionMethod = $actionMethodName;
|
|
ViewModel = $foundViewModel;
|
|
} |