├── .gitignore ├── LinqToSqlScaffolding ├── InstallationDummyFile.txt ├── LinqToSqlScaffolding.csproj ├── LinqToSqlScaffolding.nuspec ├── Properties │ └── AssemblyInfo.cs ├── Scaffolders │ ├── DataContext │ │ ├── DbContext.cs.t4 │ │ ├── DbContext.vb.t4 │ │ ├── DbContextEntityMember.cs.t4 │ │ ├── DbContextEntityMember.vb.t4 │ │ └── LinqToSqlScaffolding.DataContext.ps1 │ └── Repository │ │ ├── LinqToSqlScaffolding.Repository.ps1 │ │ ├── Repository.cs.t4 │ │ └── Repository.vb.t4 └── install.ps1 ├── MvcScaffolding ├── AppendStandardCodeToViews.bat ├── InstallationDummyFile.txt ├── MvcScaffolding.csproj ├── MvcScaffolding.nuspec ├── Properties │ └── AssemblyInfo.cs ├── Scaffolders │ ├── Action │ │ ├── Action.cs.t4 │ │ ├── Action.vb.t4 │ │ ├── ActionPost.cs.t4 │ │ ├── ActionPost.vb.t4 │ │ ├── MvcScaffolding.Action.ps1 │ │ ├── ViewModel.cs.t4 │ │ └── ViewModel.vb.t4 │ ├── ActionUnitTest │ │ ├── MvcScaffolding.ActionUnitTest.ps1 │ │ ├── TestClass.cs.t4 │ │ ├── TestClass.vb.t4 │ │ ├── TestMethod.cs.t4 │ │ └── TestMethod.vb.t4 │ ├── ActionWithUnitTest │ │ └── MvcScaffolding.ActionWithUnitTest.ps1 │ ├── AspxView │ │ ├── Create.cs.t4 │ │ ├── Create.vb.t4 │ │ ├── CreateOrEdit.cs.t4 │ │ ├── CreateOrEdit.vb.t4 │ │ ├── Delete.cs.t4 │ │ ├── Delete.vb.t4 │ │ ├── Details.cs.t4 │ │ ├── Details.vb.t4 │ │ ├── Edit.cs.t4 │ │ ├── Edit.vb.t4 │ │ ├── Empty.cs.t4 │ │ ├── Empty.vb.t4 │ │ ├── Index.cs.t4 │ │ ├── Index.vb.t4 │ │ └── MvcScaffolding.AspxView.ps1 │ ├── Controller │ │ ├── ControllerWithContext.cs.t4 │ │ ├── ControllerWithContext.vb.t4 │ │ ├── ControllerWithRepository.cs.t4 │ │ ├── ControllerWithRepository.vb.t4 │ │ ├── MvcScaffolding.Controller.ps1 │ │ └── MvcScaffolding.ControllerWithRepository.ps1 │ ├── RazorView │ │ ├── Create.cs.t4 │ │ ├── Create.vb.t4 │ │ ├── Delete.cs.t4 │ │ ├── Delete.vb.t4 │ │ ├── Details.cs.t4 │ │ ├── Details.vb.t4 │ │ ├── Edit.cs.t4 │ │ ├── Edit.vb.t4 │ │ ├── Empty.cs.t4 │ │ ├── Empty.vb.t4 │ │ ├── Index.cs.t4 │ │ ├── Index.vb.t4 │ │ ├── MvcScaffolding.RazorView.ps1 │ │ ├── _CreateOrEdit.cs.t4 │ │ └── _CreateOrEdit.vb.t4 │ └── Views │ │ ├── MvcScaffolding.Views.ps1 │ │ ├── ViewTemplateCode.cs.t4 │ │ └── ViewTemplateCode.vb.t4 ├── init.ps1 ├── install.ps1 ├── registerWithMvcTooling.ps1 └── scaffoldViaDialogTempScript.ps1 ├── README.md ├── ReferenceAssemblies ├── NuGet.Console.Types.dll └── NuGet.VisualStudio.Test.dll ├── Scaffolding.sln ├── T4Scaffolding.Core ├── Cmdlets │ ├── AddClassMemberCmdlet.cs │ ├── AddClassMemberViaTemplateCmdlet.cs │ ├── AddProjectItemViaTemplateCmdlet.cs │ ├── FindScaffolderTemplateCmdlet.cs │ ├── GetDefaultScaffolderCmdlet.cs │ ├── GetPluralizedWordCmdlet.cs │ ├── GetPrimaryKeyCmdlet.cs │ ├── GetProjectAspNetMvcVersionCmdlet.cs │ ├── GetProjectFolderCmdlet.cs │ ├── GetProjectItemCmdlet.cs │ ├── GetProjectLanguageCmdlet.cs │ ├── GetProjectTypeCmdlet.cs │ ├── GetRelatedEntitiesCmdlet.cs │ ├── GetScaffolderCmdlet.cs │ ├── GetSingularizedWordCmdlet.cs │ ├── GlobalCommandRunner.cs │ ├── InvokeScaffoldTemplateCmdlet.cs │ ├── InvokeScaffolderCmdlet.cs │ ├── ScaffoldingBaseCmdlet.cs │ ├── SetDefaultScaffolderCmdlet.cs │ └── SetIsCheckedOutCmdlet.cs ├── ControllerScaffolderAttribute.cs ├── Core │ ├── CommandInvokers │ │ ├── DefaultPowershellCommandInvoker.cs │ │ └── IPowershellCommandInvoker.cs │ ├── Configuration │ │ ├── DefaultScaffolderConfigEntry.cs │ │ ├── IScaffoldingConfigStore.cs │ │ ├── XmlScaffoldingConfig.cs │ │ └── XmlScaffoldingConfigStore.cs │ ├── EnvDTE │ │ └── EnvDTEExtensions.cs │ ├── FileSystem │ │ ├── DefaultFileSystem.cs │ │ └── IFileSystem.cs │ ├── PrimaryKeyLocators │ │ ├── IPrimaryKeyLocator.cs │ │ └── PrimaryKeyLocation.cs │ ├── ProjectTypeLocators │ │ ├── EnvDTETypeLocator.cs │ │ └── IProjectTypeLocator.cs │ ├── RelatedEntityLocators │ │ ├── IRelatedEntityLocator.cs │ │ ├── RelatedEntityInfo.cs │ │ ├── RelatedEntityLocation.cs │ │ └── RelationType.cs │ ├── ScaffolderLocators │ │ ├── IScaffolderLocator.cs │ │ ├── Ps1ScaffolderLocator.cs │ │ └── ScaffolderInfo.cs │ ├── ScaffoldingConstants.cs │ ├── Templating │ │ ├── DynamicTextTemplatingEngineHost.cs │ │ ├── DynamicViewModel.cs │ │ └── ModelPropertyClassFeatures.cs │ ├── VsConstants.cs │ └── VsProjectExtensions.cs ├── InstallationDummyFile.txt ├── Namespaces.cs ├── Properties │ └── AssemblyInfo.cs ├── ScaffolderAttribute.cs ├── Scaffolders │ ├── CustomScaffolder │ │ ├── DefaultPs1Script.ps1.t4 │ │ ├── DefaultT4Template.cs.t4 │ │ ├── DefaultT4Template.vb.t4 │ │ └── T4Scaffolding.CustomScaffolder.ps1 │ └── CustomTemplate │ │ └── T4Scaffolding.CustomTemplate.ps1 ├── T4Scaffolding.Core.csproj ├── T4Scaffolding.Core.nuspec ├── T4Scaffolding.Format.ps1xml ├── ViewScaffolderAttribute.cs ├── init.ps1 ├── install.ps1 ├── scaffoldingTabExpansion.psm1 └── uninstall.ps1 ├── T4Scaffolding.NuGetServices ├── ConsoleInitializer.cs ├── ExtensionMethods │ ├── PackageExtensions.cs │ ├── ProjectExtensions.cs │ └── SolutionExtensions.cs ├── Properties │ └── AssemblyInfo.cs ├── ScaffoldingNuGetBaseCmdlet.cs ├── Services │ ├── IPackage.cs │ ├── IPackageManager.cs │ ├── IPackagePathResolver.cs │ ├── IPackageRepository.cs │ ├── ISolutionManager.cs │ ├── IVsPackageManagerFactory.cs │ ├── PowerShellPackageManager.cs │ ├── PowerShellPackageManagerFactory.cs │ ├── PowerShellPackageRepository.cs │ ├── ScaffoldingPackagePathResolver.cs │ └── ScaffoldingSolutionManager.cs ├── T4Scaffolding.NuGetServices.csproj ├── Threading │ ├── CallStackDepthCounter.cs │ └── OperationDispatcher.cs ├── VsConstants.cs ├── VsServiceProvider.cs └── packages.config ├── T4Scaffolding.Test ├── ExampleModels │ └── PersonTemplateModel.cs ├── ExampleScripts │ ├── notAScaffolder.ps1 │ ├── scaffolderThatAcceptsParameters.ps1 │ └── simpleScaffolder.ps1 ├── ExampleTemplates │ ├── fixedStringTemplate.t4 │ ├── personTemplate.t4 │ ├── simpleTemplate.t4 │ └── templateWithOutputExtension.t4 ├── FindScaffolderTemplateCmdletTest.cs ├── GetDefaultScaffolderCmdletTest.cs ├── GetPluralizedWordCmdletTest.cs ├── GetPrimaryKeyCmdletTest.cs ├── GetProjectFolderCmdletTest.cs ├── GetProjectItemCmdletTest.cs ├── GetProjectLanguageCmdletTest.cs ├── GetRelatedEntitiesCmdletTest.cs ├── GetScaffolderCmdletTest.cs ├── GetSingularizedWordCmdletTest.cs ├── InvokeScaffoldTemplateCmdletTest.cs ├── InvokeScaffolderCmdletTest.cs ├── Properties │ └── AssemblyInfo.cs ├── Ps1ScaffolderLocatorTest.cs ├── SetDefaultScaffolderCmdletTest.cs ├── T4Scaffolding.Test.csproj ├── T4Scaffolding.Test.csproj.vspscc ├── TemplatingTest.cs ├── TestUtils │ ├── CmdletExtensions.cs │ ├── ExampleScripts.cs │ ├── ExampleTemplates.cs │ ├── MockCodeClassBuilder.cs │ ├── MockFileSystemExtensions.cs │ └── MockSolutionManagerBuilder.cs └── packages.config ├── T4Scaffolding ├── InstallationDummyFile.txt ├── Properties │ └── AssemblyInfo.cs ├── Scaffolders │ ├── EFDbContext │ │ ├── DbContext.cs.t4 │ │ ├── DbContext.vb.t4 │ │ ├── DbContextEntityMember.cs.t4 │ │ ├── DbContextEntityMember.vb.t4 │ │ └── T4Scaffolding.EFDbContext.ps1 │ └── EFRepository │ │ ├── Repository.cs.t4 │ │ ├── Repository.vb.t4 │ │ └── T4Scaffolding.EFRepository.ps1 ├── T4Scaffolding.csproj ├── T4Scaffolding.nuspec ├── init.ps1 └── install.ps1 └── Tools └── NuPack.exe /.gitignore: -------------------------------------------------------------------------------- 1 | *.nupkg 2 | obj 3 | bin 4 | packages 5 | *.suo 6 | /.vs/slnx.sqlite 7 | *.suo 8 | .vs 9 | *.vssscc 10 | -------------------------------------------------------------------------------- /LinqToSqlScaffolding/InstallationDummyFile.txt: -------------------------------------------------------------------------------- 1 | This file is added as part of the NuGet package installation process for the scaffolding package. 2 | It should be deleted automatically after installation is completed. If not, you can delete it manually. -------------------------------------------------------------------------------- /LinqToSqlScaffolding/LinqToSqlScaffolding.nuspec: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | LinqToSqlScaffolding 5 | 0.3.1 6 | Steve Sanderson 7 | Scaffolders for LINQ to SQL repositories and data contexts 8 | Scaffolders for LINQ to SQL repositories and data contexts 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /LinqToSqlScaffolding/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("LinqToSqlScaffolding")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Microsoft")] 12 | [assembly: AssemblyProduct("LinqToSqlScaffolding")] 13 | [assembly: AssemblyCopyright("Copyright © Microsoft 2011")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("59362b46-6d08-47e8-b43e-c2b7ec88d8b1")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /LinqToSqlScaffolding/Scaffolders/DataContext/DbContext.cs.t4: -------------------------------------------------------------------------------- 1 | <#@ Template Language="C#" HostSpecific="True" Inherits="DynamicTransform" #> 2 | <#@ Output Extension="cs" #> 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Data.Linq; 6 | using System.Linq; 7 | using System.Configuration; 8 | 9 | namespace <#= Model.DbContextNamespace #> 10 | { 11 | public partial class <#= Model.DbContextType #> 12 | { 13 | private readonly DataContext dataContext; 14 | 15 | public <#= Model.DbContextType #>() 16 | { 17 | var connectionString = ConfigurationManager.ConnectionStrings["ApplicationServices"].ConnectionString; 18 | dataContext = new DataContext(connectionString); 19 | } 20 | 21 | public void SaveChanges() 22 | { 23 | dataContext.SubmitChanges(); 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /LinqToSqlScaffolding/Scaffolders/DataContext/DbContext.vb.t4: -------------------------------------------------------------------------------- 1 | <#@ Template Language="C#" HostSpecific="True" Inherits="DynamicTransform" #> 2 | <#@ Output Extension="vb" #> 3 | Imports System.Data.Linq 4 | Imports System.Configuration 5 | 6 | <#= T4Scaffolding.Namespaces.BeginVb(Model.DbContextNamespace, Model.DefaultNamespace) #> 7 | Public Partial Class <#= Model.DbContextType #> 8 | Private ReadOnly dataContext As DataContext 9 | 10 | Public Sub New() 11 | Dim connectionString = ConfigurationManager.ConnectionStrings("ApplicationServices").ConnectionString 12 | dataContext = New DataContext(connectionString) 13 | End Sub 14 | 15 | Public Sub SaveChanges() 16 | dataContext.SubmitChanges() 17 | End Sub 18 | End Class 19 | <#= T4Scaffolding.Namespaces.EndVb(Model.DbContextNamespace, Model.DefaultNamespace) #> -------------------------------------------------------------------------------- /LinqToSqlScaffolding/Scaffolders/DataContext/DbContextEntityMember.cs.t4: -------------------------------------------------------------------------------- 1 | <#@ Template Language="C#" HostSpecific="True" Inherits="DynamicTransform" #> 2 | public Table<<#= ((EnvDTE.CodeType)Model.EntityType).FullName #>> <#= Model.EntityTypeNamePluralized #> { 3 | get { return dataContext.GetTable<<#= ((EnvDTE.CodeType)Model.EntityType).FullName #>>(); } 4 | } -------------------------------------------------------------------------------- /LinqToSqlScaffolding/Scaffolders/DataContext/DbContextEntityMember.vb.t4: -------------------------------------------------------------------------------- 1 | <#@ Template Language="C#" HostSpecific="True" Inherits="DynamicTransform" #> 2 | 3 | Public ReadOnly Property <#= Model.EntityTypeNamePluralized #> As Table(Of <#= ((EnvDTE.CodeType)Model.EntityType).FullName #>) 4 | Get 5 | Return dataContext.GetTable(Of Global.<#= ((EnvDTE.CodeType)Model.EntityType).FullName #>)() 6 | End Get 7 | End Property -------------------------------------------------------------------------------- /LinqToSqlScaffolding/Scaffolders/DataContext/LinqToSqlScaffolding.DataContext.ps1: -------------------------------------------------------------------------------- 1 | [T4Scaffolding.Scaffolder(Description = "Creates a LINQ to SQL DataContext class")][CmdletBinding()] 2 | param( 3 | [parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)][string]$ModelType, 4 | [parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)][string]$DbContextType, 5 | [string]$Area, 6 | [string]$Project, 7 | [string]$CodeLanguage, 8 | [string[]]$TemplateFolders 9 | ) 10 | 11 | # Ensure you've referenced System.Data.Linq 12 | (Get-Project $Project).Object.References.Add("System.Data.Linq") | Out-Null 13 | 14 | # Inherit all other logic from T4Scaffolding.EFDbContext 15 | Scaffold T4Scaffolding.EFDbContext -ModelType $ModelType -DbContextType $DbContextType -Area $Area -Project $Project -CodeLanguage $CodeLanguage -OverrideTemplateFolders $TemplateFolders -------------------------------------------------------------------------------- /LinqToSqlScaffolding/Scaffolders/Repository/LinqToSqlScaffolding.Repository.ps1: -------------------------------------------------------------------------------- 1 | [T4Scaffolding.Scaffolder(Description = "Creates a repository")][CmdletBinding()] 2 | param( 3 | [parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)][string]$ModelType, 4 | [string]$DbContextType, 5 | [string]$Area, 6 | [string]$Project, 7 | [string]$CodeLanguage, 8 | [switch]$NoChildItems = $false, 9 | [string[]]$TemplateFolders, 10 | [switch]$Force = $false 11 | ) 12 | 13 | # Inherit all logic from T4Scaffolding.EFRepository. Override the template by passing $TemplateFolders from this scaffolder. 14 | Scaffold T4Scaffolding.EFRepository -ModelType $ModelType -DbContextType $DbContextType -Area $Area -Project $Project -CodeLanguage $CodeLanguage -NoChildItems:$true -OverrideTemplateFolders $TemplateFolders -Force:$Force 15 | 16 | if(!$NoChildItems) { 17 | if(!$DbContextType) { $DbContextType = [System.Text.RegularExpressions.Regex]::Replace((Get-Project $Project).Name, "[^a-zA-Z0-9]", "") + "Context" } 18 | Scaffold LinqToSqlDataContext -ModelType $ModelType -DbContextType $DbContextType -Area $Area -Project $Project -CodeLanguage $CodeLanguage 19 | } -------------------------------------------------------------------------------- /LinqToSqlScaffolding/Scaffolders/Repository/Repository.cs.t4: -------------------------------------------------------------------------------- 1 | <#@ template language="C#" HostSpecific="True" inherits="DynamicTransform" #> 2 | <#@ import namespace="System.Linq" #> 3 | <#@ import namespace="EnvDTE" #> 4 | <#@ Output Extension="cs" #> 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Linq.Expressions; 9 | using System.Web; 10 | <# if((!string.IsNullOrEmpty(Model.ModelTypeNamespace)) && (Model.ModelTypeNamespace != Model.RepositoryNamespace)) { #> 11 | using <#= Model.ModelTypeNamespace #>; 12 | <# } #> 13 | 14 | namespace <#= Model.RepositoryNamespace #> 15 | { 16 | <# 17 | var modelType = (CodeType)Model.ModelType; 18 | var modelName = modelType.Name; 19 | var modelNamePlural = Model.ModelTypePluralized; 20 | var contextName = Model.DbContextType; 21 | var primaryKeyProperty = modelType.VisibleMembers().OfType().Single(x => x.Name == Model.PrimaryKey); 22 | #> 23 | public class <#= modelName #>Repository : I<#= modelName #>Repository 24 | { 25 | <#= contextName #> context = new <#= contextName #>(); 26 | 27 | public IQueryable<<#= modelName #>> All 28 | { 29 | get { return context.<#= modelNamePlural #>; } 30 | } 31 | 32 | public IQueryable<<#= modelName #>> AllIncluding(params Expression, object>>[] includeProperties) 33 | { 34 | // Todo: Support eager loading 35 | return context.<#= modelNamePlural #>; 36 | } 37 | 38 | public <#= modelName #> Find(<#= primaryKeyProperty.Type.AsString #> id) 39 | { 40 | return context.<#= modelNamePlural #>.SingleOrDefault(x => x.<#= Model.PrimaryKey #> == id); 41 | } 42 | 43 | public void InsertOrUpdate(<#= modelName #> <#= modelName.ToLower() #>) 44 | { 45 | if (<#= modelName.ToLower() #>.<#= Model.PrimaryKey #> == default(<#= primaryKeyProperty.Type.AsString #>)) { 46 | // New entity 47 | <# if(primaryKeyProperty.Type.AsString == "System.Guid") { #> 48 | <#= modelName.ToLower() #>.<#= primaryKeyProperty.Name #> = Guid.NewGuid(); 49 | <# } #> 50 | context.<#= modelNamePlural #>.InsertOnSubmit(<#= modelName.ToLower() #>); 51 | } else { 52 | // Existing entity 53 | context.<#= modelNamePlural #>.Attach(<#= modelName.ToLower() #>, true); 54 | } 55 | } 56 | 57 | public void Delete(<#= primaryKeyProperty.Type.AsString #> id) 58 | { 59 | var itemToDelete = Find(id); 60 | context.<#= modelNamePlural #>.DeleteOnSubmit(itemToDelete); 61 | } 62 | 63 | public void Save() 64 | { 65 | context.SaveChanges(); 66 | } 67 | } 68 | 69 | public interface I<#= modelName #>Repository 70 | { 71 | IQueryable<<#= modelName #>> All { get; } 72 | IQueryable<<#= modelName #>> AllIncluding(params Expression, object>>[] includeProperties); 73 | <#= modelName #> Find(<#= primaryKeyProperty.Type.AsString #> id); 74 | void InsertOrUpdate(<#= modelName #> <#= modelName.ToLower() #>); 75 | void Delete(<#= primaryKeyProperty.Type.AsString #> id); 76 | void Save(); 77 | } 78 | } -------------------------------------------------------------------------------- /LinqToSqlScaffolding/Scaffolders/Repository/Repository.vb.t4: -------------------------------------------------------------------------------- 1 | <#@ template language="C#" HostSpecific="True" inherits="DynamicTransform" #> 2 | <#@ import namespace="System.Linq" #> 3 | <#@ import namespace="EnvDTE" #> 4 | <#@ Output Extension="vb" #> 5 | Imports System.Collections.Generic 6 | Imports System.Linq 7 | Imports System.Linq.Expressions 8 | <# if((!string.IsNullOrEmpty(Model.ModelTypeNamespace)) && (Model.ModelTypeNamespace != Model.RepositoryNamespace)) { #> 9 | Imports <#= Model.ModelTypeNamespace #> 10 | <# } #> 11 | 12 | <#= T4Scaffolding.Namespaces.BeginVb(Model.RepositoryNamespace, Model.DefaultNamespace) #> 13 | <# 14 | var modelType = (CodeType)Model.ModelType; 15 | var modelName = modelType.Name; 16 | var modelNamePlural = Model.ModelTypePluralized; 17 | var contextName = Model.DbContextType; 18 | var primaryKeyProperty = modelType.VisibleMembers().OfType().Single(x => x.Name == Model.PrimaryKey); 19 | #> 20 | Public Class <#= modelName #>Repository : Implements I<#= modelName #>Repository 21 | Private context As <#= contextName #> = New <#= contextName #>() 22 | 23 | Public ReadOnly Property All As IQueryable(Of <#= modelName #>) Implements I<#= modelName #>Repository.All 24 | Get 25 | Return context.<#= modelNamePlural #> 26 | End Get 27 | End Property 28 | 29 | Public Function AllIncluding(ByVal ParamArray includeProperties() As Expression(Of Func(Of <#= modelName #>, Object))) As IQueryable(Of <#= modelName #>) Implements I<#= modelName #>Repository.AllIncluding 30 | ' Todo: Support eager loading 31 | Return context.<#= modelNamePlural #> 32 | End Function 33 | 34 | Public Function Find(ByVal id As <#= primaryKeyProperty.Type.AsString #>) As <#= modelName #> Implements I<#= modelName #>Repository.Find 35 | Return context.<#= modelNamePlural #>.SingleOrDefault(Function(x) x.<#= Model.PrimaryKey #> = id) 36 | End Function 37 | 38 | Public Sub InsertOrUpdate(<#= modelName.ToLower() #> As <#= modelName #>) Implements I<#= modelName #>Repository.InsertOrUpdate 39 | If <#= modelName.ToLower() #>.<#= Model.PrimaryKey #> = Nothing Then 40 | ' New entity 41 | <# if(primaryKeyProperty.Type.AsString == "System.Guid") { #> 42 | <#= modelName.ToLower() #>.<#= primaryKeyProperty.Name #> = Guid.NewGuid() 43 | <# } #> 44 | context.<#= modelNamePlural #>.InsertOnSubmit(<#= modelName.ToLower() #>) 45 | Else 46 | ' Existing entity 47 | context.<#= modelNamePlural #>.Attach(<#= modelName.ToLower() #>, True) 48 | End If 49 | End Sub 50 | 51 | Public Sub Delete(ByVal id As <#= primaryKeyProperty.Type.AsString #>) Implements I<#= modelName #>Repository.Delete 52 | Dim itemToDelete = Find(id) 53 | context.<#= modelNamePlural #>.DeleteOnSubmit(itemToDelete) 54 | End Sub 55 | 56 | Public Sub Save() Implements I<#= modelName #>Repository.Save 57 | context.SaveChanges() 58 | End Sub 59 | End Class 60 | 61 | Public Interface I<#= modelName #>Repository 62 | ReadOnly Property All As IQueryable(Of <#= modelName #>) 63 | Function AllIncluding(ByVal ParamArray includeProperties() As Expression(Of Func(Of <#= modelName #>, Object))) As IQueryable(Of <#= modelName #>) 64 | Function Find(id As <#= primaryKeyProperty.Type.AsString #>) As <#= modelName #> 65 | Sub InsertOrUpdate(<#= modelName.ToLower() #> As <#= modelName #>) 66 | Sub Delete(id As <#= primaryKeyProperty.Type.AsString #>) 67 | Sub Save() 68 | End Interface 69 | <#= T4Scaffolding.Namespaces.EndVb(Model.RepositoryNamespace, Model.DefaultNamespace) #> -------------------------------------------------------------------------------- /LinqToSqlScaffolding/install.ps1: -------------------------------------------------------------------------------- 1 | param($rootPath, $toolsPath, $package, $project) 2 | 3 | # Try to delete InstallationDummyFile.txt 4 | if ($project) { 5 | $project.ProjectItems | ?{ $_.Name -eq "InstallationDummyFile.txt" } | %{ $_.Delete() } 6 | } 7 | 8 | # Bail out if scaffolding is disabled (probably because you're running an incompatible version of T4Scaffolding.dll) 9 | if (-not (Get-Module T4Scaffolding)) { return } 10 | 11 | Set-DefaultScaffolder -Name LinqToSqlDataContext -Scaffolder LinqToSqlScaffolding.DataContext -SolutionWide -DoNotOverwriteExistingSetting -------------------------------------------------------------------------------- /MvcScaffolding/AppendStandardCodeToViews.bat: -------------------------------------------------------------------------------- 1 | set OutputPath=%1 2 | set ViewsNeedingCode=(RazorView\_CreateOrEdit, RazorView\Create, RazorView\Delete, RazorView\Details, RazorView\Edit, RazorView\Index, AspxView\CreateOrEdit, AspxView\Create, AspxView\Delete, AspxView\Details, AspxView\Edit, AspxView\Index) 3 | 4 | for %%x in %ViewsNeedingCode% do ( 5 | type Scaffolders\Views\ViewTemplateCode.cs.t4 >> %OutputPath%\Scaffolders\%%x.cs.t4; 6 | type Scaffolders\Views\ViewTemplateCode.vb.t4 >> %OutputPath%\Scaffolders\%%x.vb.t4; 7 | ) -------------------------------------------------------------------------------- /MvcScaffolding/InstallationDummyFile.txt: -------------------------------------------------------------------------------- 1 | This file is added as part of the NuGet package installation process for the scaffolding package. 2 | It should be deleted automatically after installation is completed. If not, you can delete it manually. -------------------------------------------------------------------------------- /MvcScaffolding/MvcScaffolding.nuspec: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | MvcScaffolding.VS2017 5 | 1.0.2 6 | Scott Hanselman, Steve Sanderson, David Anderson, Cigano Morrison Mendez 7 | MvcScaffolding (Fix VS2017) 8 | A fast and customizable way to add controllers, views, and other items to your ASP.NET MVC application 9 | A fast and customizable way to add controllers, views, and other items to your ASP.NET MVC application 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /MvcScaffolding/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("MvcScaffolding")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Microsoft")] 12 | [assembly: AssemblyProduct("MvcScaffolding")] 13 | [assembly: AssemblyCopyright("Copyright © Microsoft 2011")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("8de9c2e3-b5da-46f1-9e01-cb18df972493")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /MvcScaffolding/Scaffolders/Action/Action.cs.t4: -------------------------------------------------------------------------------- 1 | <#@ Template Language="C#" HostSpecific="True" Inherits="DynamicTransform" #> 2 | <# var viewModel = (EnvDTE.CodeType)Model.ViewModel; #> 3 | public ViewResult <#= Model.Action #>() 4 | { 5 | <# if (viewModel == null) { #> 6 | return View(); 7 | <# } else { #> 8 | return View(new <#= viewModel.Name #> { 9 | // Populate properties here 10 | }); 11 | <# } #> 12 | } -------------------------------------------------------------------------------- /MvcScaffolding/Scaffolders/Action/Action.vb.t4: -------------------------------------------------------------------------------- 1 | <#@ Template Language="VB" HostSpecific="True" Inherits="DynamicTransform" #> 2 | <# Dim viewModel = CType(Model.ViewModel, EnvDTE.CodeType) #> 3 | 4 | Public Function <#= Model.Action #>() As ViewResult 5 | <# If viewModel Is Nothing Then #> 6 | Return View() 7 | <# Else #> 8 | Return View(New <#= viewModel.Name #>()) 9 | <# End If #> 10 | End Function -------------------------------------------------------------------------------- /MvcScaffolding/Scaffolders/Action/ActionPost.cs.t4: -------------------------------------------------------------------------------- 1 | <#@ Template Language="C#" HostSpecific="True" Inherits="DynamicTransform" #> 2 | <# var viewModel = (EnvDTE.CodeType)Model.ViewModel; #> 3 | [HttpPost, ActionName("<#= Model.Action #>")] 4 | public ActionResult <#= Model.Action #>Post(<# if (viewModel != null) { #><#= viewModel.Name #> <#= viewModel.Name.ToLower() #><# } #>) 5 | { 6 | if (ModelState.IsValid) { 7 | return RedirectToAction("Index"); 8 | } else { 9 | return View(<# if (viewModel != null) { #><#= viewModel.Name.ToLower() #><# } #>); 10 | } 11 | } -------------------------------------------------------------------------------- /MvcScaffolding/Scaffolders/Action/ActionPost.vb.t4: -------------------------------------------------------------------------------- 1 | <#@ Template Language="VB" HostSpecific="True" Inherits="DynamicTransform" #> 2 | <# Dim viewModel = CType(Model.ViewModel, EnvDTE.CodeType) #> 3 | 4 | ")> 5 | Public Function <#= Model.Action #>Post(<# If viewModel IsNot Nothing Then #>ByVal <#= viewModel.Name.ToLower() #> As <#= viewModel.Name #><# End If #>) As ActionResult 6 | If ModelState.IsValid Then 7 | Return RedirectToAction("Index") 8 | Else 9 | Return View(<# If viewModel IsNot Nothing Then #><#= viewModel.Name.ToLower() #><# End If #>) 10 | End If 11 | End Function -------------------------------------------------------------------------------- /MvcScaffolding/Scaffolders/Action/ViewModel.cs.t4: -------------------------------------------------------------------------------- 1 | <#@ Template Language="C#" HostSpecific="True" Inherits="DynamicTransform" #> 2 | <#@ Output Extension="cs" #> 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | 7 | namespace <#= Model.Namespace #> 8 | { 9 | public class <#= Model.ClassName #> 10 | { 11 | // Add properties here 12 | } 13 | } -------------------------------------------------------------------------------- /MvcScaffolding/Scaffolders/Action/ViewModel.vb.t4: -------------------------------------------------------------------------------- 1 | <#@ Template Language="VB" HostSpecific="True" Inherits="DynamicTransform" #> 2 | <#@ Output Extension="vb" #> 3 | <#= T4Scaffolding.Namespaces.BeginVb(Model.Namespace, Model.DefaultNamespace) #> 4 | Public Class <#= Model.ClassName #> 5 | ' Add properties here 6 | End Class 7 | <#= T4Scaffolding.Namespaces.EndVb(Model.Namespace, Model.DefaultNamespace) #> -------------------------------------------------------------------------------- /MvcScaffolding/Scaffolders/ActionUnitTest/MvcScaffolding.ActionUnitTest.ps1: -------------------------------------------------------------------------------- 1 | [T4Scaffolding.Scaffolder(Description = "Creates a unit test stub for an action method")][CmdletBinding()] 2 | param( 3 | [parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)][string]$Controller, 4 | [parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)][string]$Action, 5 | [string]$ViewModel, 6 | [switch]$WithViewModel, 7 | [string]$Project, 8 | [string]$CodeLanguage, 9 | [string[]]$TemplateFolders, 10 | [switch]$Force = $false 11 | ) 12 | 13 | # Ensure the controller name ends with "Controller" 14 | $Controller = [System.Text.RegularExpressions.Regex]::Replace($Controller, "Controller$", "", [System.Text.RegularExpressions.RegexOptions]::IgnoreCase) + "Controller" 15 | 16 | # Find the unit test project, or abort 17 | $unitTestProject = Get-Project ($Project + ".Test") -ErrorAction SilentlyContinue 18 | if (!$unitTestProject) { $unitTestProject = Get-Project ($Project + ".Tests") -ErrorAction SilentlyContinue } 19 | if (!$unitTestProject) { throw "Cannot find a unit test project corresponding to project '$Project'" } 20 | 21 | # Ensure you've referenced System.Web.Mvc 22 | $unitTestProject.Object.References.Add("System.Web.Mvc") | Out-Null 23 | 24 | # Create the test fixture class 25 | $foundControllerClass = Get-ProjectType $Controller -Project $Project 26 | if (!$foundControllerClass) { return } 27 | $testClassName = $foundControllerClass.Name + "Test" 28 | $testClassNamespace = $unitTestProject.Properties.Item("DefaultNamespace").Value 29 | $defaultNamespace = $unitTestProject.Properties.Item("DefaultNamespace").Value 30 | Add-ProjectItemViaTemplate $testClassName -Template TestClass -Model @{ ClassName = $testClassName; Namespace = $testClassNamespace; DefaultNamespace = $defaultNamespace; Controller = [MarshalByRefObject]$foundControllerClass } ` 31 | -SuccessMessage "Added unit test class at {0}" -TemplateFolders $TemplateFolders -Project $unitTestProject.Name -CodeLanguage $CodeLanguage -Force:$Force 32 | 33 | # Add a test method to it 34 | if ($WithViewModel -and !$ViewModel) { $ViewModel = $Action + "ViewModel" } 35 | $foundViewModel = if ($ViewModel) { Get-ProjectType $ViewModel -Project $Project } 36 | if ($ViewModel -and !$foundViewModel) { return } 37 | $testClass = Get-ProjectType $testClassName -Project $unitTestProject.Name 38 | $testMethodName = $Action + "Test" 39 | Add-ClassMemberViaTemplate -Name $testMethodName -CodeClass $testClass -Template TestMethod -Model @{ 40 | TestMethod = $testMethodName; 41 | ActionMethod = $Action; 42 | Controller = [MarshalByRefObject]$foundControllerClass; 43 | ViewModel = [MarshalByRefObject]$foundViewModel; 44 | } -SuccessMessage "Added unit test method $testMethodName to $($testClass.Name)" ` 45 | -TemplateFolders $TemplateFolders -Project $unitTestProject.Name -CodeLanguage $CodeLanguage -Force:$Force 46 | 47 | # Also import the view model namespace if not already imported 48 | if ($foundViewModel) { 49 | $existingImport = $testClass.ProjectItem.FileCodeModel.CodeElements | ?{ ($_.Kind -eq 35) -and ($_.Namespace -eq $foundViewModel.Namespace.FullName) } 50 | if (!$existingImport) { 51 | $testClass.ProjectItem.FileCodeModel.AddImport($foundViewModel.Namespace.FullName) | Out-Null 52 | } 53 | } -------------------------------------------------------------------------------- /MvcScaffolding/Scaffolders/ActionUnitTest/TestClass.cs.t4: -------------------------------------------------------------------------------- 1 | <#@ Template Language="C#" HostSpecific="True" Inherits="DynamicTransform" #> 2 | <#@ Output Extension="cs" #> 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using Microsoft.VisualStudio.TestTools.UnitTesting; 7 | using <#= ((EnvDTE.CodeType)Model.Controller).Namespace.FullName #>; 8 | 9 | namespace <#= Model.Namespace #> 10 | { 11 | [TestClass] 12 | public class <#= Model.ClassName #> 13 | { 14 | } 15 | } -------------------------------------------------------------------------------- /MvcScaffolding/Scaffolders/ActionUnitTest/TestClass.vb.t4: -------------------------------------------------------------------------------- 1 | <#@ Template Language="VB" HostSpecific="True" Inherits="DynamicTransform" #> 2 | <#@ Output Extension="vb" #> 3 | <# If CType(Model.Controller, EnvDTE.CodeType).Namespace IsNot Nothing Then #> 4 | Imports <#= CType(Model.Controller, EnvDTE.CodeType).Namespace.FullName #> 5 | 6 | <# End If #> 7 | <#= If(T4Scaffolding.Namespaces.BeginVb(Model.Namespace, Model.DefaultNamespace), "") #> 8 | 9 | Public Class <#= Model.ClassName #> 10 | End Class 11 | <#= If(T4Scaffolding.Namespaces.EndVb(Model.Namespace, Model.DefaultNamespace), "") #> -------------------------------------------------------------------------------- /MvcScaffolding/Scaffolders/ActionUnitTest/TestMethod.cs.t4: -------------------------------------------------------------------------------- 1 | <#@ Template Language="C#" HostSpecific="True" Inherits="DynamicTransform" #> 2 | <#@ assembly name="System.Web.Mvc" #> 3 | <#@ import namespace="System.Linq" #> 4 | <#@ import namespace="EnvDTE" #> 5 | <# 6 | var viewModel = (CodeType)Model.ViewModel; 7 | var actionMethodInfo = ((CodeType)Model.Controller).VisibleMembers().OfType().FirstOrDefault(x => x.Name == Model.ActionMethod); 8 | var defaultActionMethodArgs = actionMethodInfo == null ? null : actionMethodInfo.Parameters.OfType().Select(x => x.Type.CodeType != null && x.Type.CodeType.Kind == vsCMElement.vsCMElementClass ? "null" : "default(" + x.Type.AsString + ")"); 9 | #> 10 | [TestMethod] 11 | public void <#= Model.TestMethod #>() 12 | { 13 | // Arrange 14 | var controller = new <#= ((EnvDTE.CodeType)Model.Controller).Name #>(); 15 | 16 | // Act 17 | <# if (actionMethodInfo == null) { #> 18 | 19 | // Assert 20 | <# } else if (actionMethodInfo.Type.IsType()) { #> 21 | var viewResult = controller.<#= Model.ActionMethod #>(<#= string.Join(", ", defaultActionMethodArgs.ToArray()) #>); 22 | var viewModel = <# if (viewModel != null) { #>(<#= viewModel.Name #>)<# } #>viewResult.Model; 23 | 24 | // Assert 25 | // Assert.AreEqual("expected value", viewModel.SomeProperty); 26 | <# } else if (actionMethodInfo.Type.IsType()) { #> 27 | var redirectToRouteResult = controller.<#= Model.ActionMethod #>(<#= string.Join(", ", defaultActionMethodArgs.ToArray()) #>); 28 | 29 | // Assert 30 | //Assert.AreEqual("ActionName", redirectToRouteResult.RouteValues["action"]); 31 | <# } else if (actionMethodInfo.Type.IsType()) { #> 32 | var actionResult = controller.<#= Model.ActionMethod #>(<#= string.Join(", ", defaultActionMethodArgs.ToArray()) #>); 33 | 34 | // Assert 35 | <# } else { #> 36 | 37 | // Assert 38 | <# } #> 39 | Assert.Inconclusive(); // Todo: Make assertions, then remove this line 40 | } -------------------------------------------------------------------------------- /MvcScaffolding/Scaffolders/ActionUnitTest/TestMethod.vb.t4: -------------------------------------------------------------------------------- 1 | <#@ Template Language="VB" HostSpecific="True" Inherits="DynamicTransform" #> 2 | <#@ assembly name="System.Web.Mvc" #> 3 | <#@ import namespace="System.Collections" #> 4 | <#@ import namespace="System.Collections.Generic" #> 5 | <#@ import namespace="System.Linq" #> 6 | <#@ import namespace="EnvDTE" #> 7 | <# 8 | Dim viewModel = CType(Model.ViewModel, CodeType) 9 | Dim actionMethodInfo = CType(Model.Controller, CodeType).VisibleMembers().OfType(Of CodeFunction)().FirstOrDefault(Function(x) x.Name = Model.ActionMethod) 10 | Dim defaultActionMethodArgs = If(actionMethodInfo Is Nothing, Nothing, System.Linq.Enumerable.Range(0, actionMethodInfo.Parameters.Count).Select(Function(x) "Nothing")) 11 | #> 12 | 13 | 14 | Public Sub <#= Model.TestMethod #>() 15 | ' Arrange 16 | Dim controller = New <#= CType(Model.Controller, EnvDTE.CodeType).Name #>() 17 | 18 | ' Act 19 | <# If actionMethodInfo Is Nothing Then #> 20 | 21 | ' Assert 22 | <# ElseIf CType(actionMethodInfo.Type, CodeTypeRef).IsType(Of System.Web.Mvc.ViewResult)() Then #> 23 | Dim viewResult = controller.<#= Model.ActionMethod #>(<#= String.Join(", ", CType(defaultActionMethodArgs, IEnumerable(Of String))) #>) 24 | Dim viewModel = <# If viewModel IsNot Nothing Then #>CType(viewResult.Model, <#= viewModel.Name #>)<# Else #>viewResult.Model<# End If #> 25 | 26 | ' Assert 27 | ' Assert.AreEqual("expected value", viewModel.SomeProperty) 28 | <# ElseIf CType(actionMethodInfo.Type, CodeTypeRef).IsType(Of System.Web.Mvc.RedirectToRouteResult)() Then #> 29 | Dim redirectToRouteResult = controller.<#= Model.ActionMethod #>(<#= String.Join(", ", CType(defaultActionMethodArgs, IEnumerable(Of String))) #>) 30 | 31 | ' Assert 32 | 'Assert.AreEqual("ActionName", redirectToRouteResult.RouteValues("action")) 33 | <# ElseIf CType(actionMethodInfo.Type, CodeTypeRef).IsType(Of System.Web.Mvc.ActionResult)() Then #> 34 | Dim actionResult = controller.<#= Model.ActionMethod #>(<#= String.Join(", ", CType(defaultActionMethodArgs, IEnumerable(Of String))) #>) 35 | 36 | ' Assert 37 | <# Else #> 38 | 39 | ' Assert 40 | <# End If #> 41 | Assert.Inconclusive() ' Todo: Make assertions, then remove this line 42 | End Sub -------------------------------------------------------------------------------- /MvcScaffolding/Scaffolders/ActionWithUnitTest/MvcScaffolding.ActionWithUnitTest.ps1: -------------------------------------------------------------------------------- 1 | [T4Scaffolding.Scaffolder(Description = "Creates an action method, view model, view, and unit test stub")][CmdletBinding()] 2 | param( 3 | [parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)][string]$Controller, 4 | [parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)][string]$Action, 5 | [string]$ViewModel, 6 | [switch]$WithViewModel, 7 | [switch]$Post, 8 | [string]$Project, 9 | [string]$CodeLanguage, 10 | [string[]]$TemplateFolders, 11 | [switch]$Force = $false 12 | ) 13 | 14 | $actionScaffoldResult = Scaffold MvcScaffolding.Action -Controller $Controller -Action $Action -ViewModel $ViewModel -WithViewModel:$WithViewModel -Post:$Post -Project $Project -CodeLanguage $CodeLanguage -OverrideTemplateFolders $TemplateFolders -Force:$Force 15 | Scaffold MvcScaffolding.ActionUnitTest -Controller $actionScaffoldResult.Controller.FullName -Action $actionScaffoldResult.ActionMethod -ViewModel $actionScaffoldResult.ViewModel.FullName -Project $Project -CodeLanguage $CodeLanguage -OverrideTemplateFolders $TemplateFolders -Force:$Force 16 | -------------------------------------------------------------------------------- /MvcScaffolding/Scaffolders/AspxView/CreateOrEdit.cs.t4: -------------------------------------------------------------------------------- 1 | <#@ Template Language="C#" HostSpecific="True" Inherits="DynamicTransform" #> 2 | <#@ Output extension="ascx" #> 3 | <#@ assembly name="System.ComponentModel.DataAnnotations" #> 4 | <#@ assembly name="System.Core" #> 5 | <#@ assembly name="System.Data.Entity" #> 6 | <#@ assembly name="System.Data.Linq" #> 7 | <#@ import namespace="System" #> 8 | <#@ import namespace="System.Collections" #> 9 | <#@ import namespace="System.Collections.Generic" #> 10 | <#@ import namespace="System.ComponentModel.DataAnnotations" #> 11 | <#@ import namespace="System.Data.Linq.Mapping" #> 12 | <#@ import namespace="System.Data.Objects.DataClasses" #> 13 | <#@ import namespace="System.Linq" #> 14 | <#@ import namespace="System.Reflection" #> 15 | <# 16 | var viewDataType = (EnvDTE.CodeType) Model.ViewDataType; 17 | var mvcViewDataTypeGenericString = (viewDataType != null) ? "<" + viewDataType.FullName + ">" : ""; 18 | #> 19 | <%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<#= mvcViewDataTypeGenericString #>" %> 20 | 21 | <# 22 | foreach (ModelProperty property in GetModelProperties(Model.ViewDataType, false)) { 23 | if (!property.IsPrimaryKey && !property.IsForeignKey && !property.IsReadOnly) { 24 | #> 25 |
26 | <%: Html.LabelFor(model => model.<#= property.Name #>) %> 27 |
28 |
29 | <%: Html.EditorFor(model => model.<#= property.Name #>) %> 30 | <%: Html.ValidationMessageFor(model => model.<#= property.Name #>) %> 31 |
32 | 33 | <# 34 | } 35 | } 36 | #> 37 | <# 38 | foreach (RelatedEntityInfo relation in ParentRelations) { 39 | #> 40 |
41 | <#= relation.RelationName #> 42 |
43 |
44 | <%: Html.DropDownListFor(model => model.<#= relation.RelationProperty.Name #>, ((IEnumerable<<#= relation.RelatedEntityType.FullName #>>)ViewBag.Possible<#= relation.RelationNamePlural #>).Select(option => new SelectListItem { 45 | Text = <#= GetValueExpression("option", relation.RelatedEntityType) #>, 46 | Value = option.<#= relation.RelatedEntityPrimaryKeyName #>.ToString(), 47 | Selected = (Model != null) && (option.<#= relation.RelatedEntityPrimaryKeyName #> == Model.<#= relation.RelationProperty.Name #>) 48 | }), "Choose...") %> 49 | <%: Html.ValidationMessageFor(model => model.<#= relation.RelationProperty.Name #>) %> 50 |
51 | <# 52 | } 53 | #> -------------------------------------------------------------------------------- /MvcScaffolding/Scaffolders/AspxView/CreateOrEdit.vb.t4: -------------------------------------------------------------------------------- 1 | <#@ Template Language="VB" HostSpecific="True" Inherits="DynamicTransform" #> 2 | <#@ Output extension="ascx" #> 3 | <#@ assembly name="System.ComponentModel.DataAnnotations" #> 4 | <#@ assembly name="System.Core" #> 5 | <#@ assembly name="System.Data.Entity" #> 6 | <#@ assembly name="System.Data.Linq" #> 7 | <#@ import namespace="System" #> 8 | <#@ import namespace="System.Collections" #> 9 | <#@ import namespace="System.Collections.Generic" #> 10 | <#@ import namespace="System.ComponentModel.DataAnnotations" #> 11 | <#@ import namespace="System.Data.Linq.Mapping" #> 12 | <#@ import namespace="System.Data.Objects.DataClasses" #> 13 | <#@ import namespace="System.Linq" #> 14 | <#@ import namespace="System.Reflection" #> 15 | <#@ import namespace="EnvDTE" #> 16 | <# 17 | Dim viewDataType = CType(Model.ViewDataType, CodeType) 18 | Dim mvcViewDataTypeGenericString As String = If(viewDataType IsNot Nothing, "(Of " & viewDataType.FullName & ")", String.Empty) 19 | #> 20 | <%@ Control Language="VB" Inherits="System.Web.Mvc.ViewUserControl<#= mvcViewDataTypeGenericString #>" %> 21 | 22 | <# 23 | For Each modelProp As ModelProperty In GetModelProperties(Model.ViewDataType, False) 24 | If (Not modelProp.IsPrimaryKey) AndAlso (Not modelProp.IsForeignKey) AndAlso (Not modelProp.IsReadOnly) Then 25 | #> 26 |
27 | <%: Html.LabelFor(Function(model) model.<#= modelProp.Name #>) %> 28 |
29 |
30 | <%: Html.EditorFor(Function(model) model.<#= modelProp.Name #>) %> 31 | <%: Html.ValidationMessageFor(Function(model) model.<#= modelProp.Name #>) %> 32 |
33 | 34 | <# 35 | End If 36 | Next 37 | #> 38 | <# For Each relation As RelatedEntityInfo In ParentRelations #> 39 |
40 | <#= relation.RelationName #> 41 |
42 |
43 | <%: Html.DropDownListFor(Function(model) model.<#= relation.RelationProperty.Name #>, CType(ViewBag.Possible<#= relation.RelationNamePlural #>, IEnumerable(Of <#= relation.RelatedEntityType.FullName #>)).Select(Function(optionValue) New SelectListItem() With { _ 44 | .Text = <#= GetValueExpression("optionValue", relation.RelatedEntityType) #>, _ 45 | .Value = optionValue.<#= relation.RelatedEntityPrimaryKeyName #>.ToString(), _ 46 | .Selected = (Model IsNot Nothing) AndAlso (optionValue.<#= relation.RelatedEntityPrimaryKeyName #>.Equals(Model.<#= relation.RelationProperty.Name #>)) _ 47 | }), "Choose...") %> 48 | <%: Html.ValidationMessageFor(Function(model) model.<#= relation.RelationProperty.Name #>) %> 49 |
50 | <# Next #> -------------------------------------------------------------------------------- /MvcScaffolding/Scaffolders/AspxView/Delete.cs.t4: -------------------------------------------------------------------------------- 1 | <#@ Template Language="C#" HostSpecific="True" Inherits="DynamicTransform" #> 2 | <#@ Output extension="aspx" #> 3 | <#@ assembly name="System.ComponentModel.DataAnnotations" #> 4 | <#@ assembly name="System.Core" #> 5 | <#@ assembly name="System.Data.Entity" #> 6 | <#@ assembly name="System.Data.Linq" #> 7 | <#@ import namespace="System" #> 8 | <#@ import namespace="System.Collections" #> 9 | <#@ import namespace="System.Collections.Generic" #> 10 | <#@ import namespace="System.ComponentModel.DataAnnotations" #> 11 | <#@ import namespace="System.Data.Linq.Mapping" #> 12 | <#@ import namespace="System.Data.Objects.DataClasses" #> 13 | <#@ import namespace="System.Linq" #> 14 | <#@ import namespace="System.Reflection" #> 15 | <# var viewDataType = (EnvDTE.CodeType) Model.ViewDataType; #> 16 | <# 17 | string mvcViewDataTypeGenericString = (viewDataType != null) ? "<" + viewDataType.FullName + ">" : ""; 18 | int CPHCounter = 1; 19 | #> 20 | <# 21 | if(Model.IsContentPage) { 22 | #> 23 | <%@ Page Title="" Language="C#" MasterPageFile="~<#= Model.Layout #>" Inherits="System.Web.Mvc.ViewPage<#= mvcViewDataTypeGenericString #>" %> 24 | 25 | <# 26 | foreach(string cphid in Model.SectionNames) { 27 | if(cphid.Equals("TitleContent", StringComparison.OrdinalIgnoreCase)) { 28 | #> 29 | 30 | <#= Model.ViewName #> 31 | 32 | 33 | <# 34 | CPHCounter++; 35 | } 36 | } 37 | #> 38 | 39 | 40 |

<#= Model.ViewName #>

41 | 42 | <# 43 | } else { 44 | #> 45 | <%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<#= mvcViewDataTypeGenericString #>" %> 46 | 47 | 48 | 49 | 50 | <#= Model.ViewName #> 51 | 52 | 53 | <# 54 | PushIndent(" "); 55 | } 56 | #> 57 |

Are you sure you want to delete this?

58 |
59 | <#= Model.ViewDataTypeName ?? String.Empty #> 60 | <# 61 | foreach (ModelProperty property in GetModelProperties(Model.ViewDataType, true)) { 62 | if (!property.IsPrimaryKey && !property.IsForeignKey) { 63 | #> 64 | 65 |
<#= property.Name #>
66 |
<%: <#= property.ValueExpression #> %>
67 | <# 68 | } 69 | } 70 | #> 71 |
72 | <% using (Html.BeginForm()) { %> 73 |

74 | | 75 | <%: Html.ActionLink("Back to List", "Index") %> 76 |

77 | <% } %> 78 | 79 | <# 80 | // The following code closes the asp:Content tag used in the case of a master page and the body and html tags in the case of a regular view page 81 | #> 82 | <# 83 | if(Model.IsContentPage) { 84 | #> 85 |
86 | <# 87 | foreach(string cphid in Model.SectionNames) { 88 | if(!cphid.Equals("TitleContent", StringComparison.OrdinalIgnoreCase) && !cphid.Equals(Model.PrimarySectionName, StringComparison.OrdinalIgnoreCase)) { 89 | CPHCounter++; 90 | #> 91 | 92 | 93 | 94 | <# 95 | } 96 | } 97 | #> 98 | <# 99 | } else if(!Model.IsContentPage) { 100 | ClearIndent(); 101 | #> 102 | 103 | 104 | <# 105 | } 106 | #> 107 | 108 | -------------------------------------------------------------------------------- /MvcScaffolding/Scaffolders/AspxView/Delete.vb.t4: -------------------------------------------------------------------------------- 1 | <#@ Template Language="VB" HostSpecific="True" Inherits="DynamicTransform" #> 2 | <#@ Output extension="aspx" #> 3 | <#@ assembly name="System.ComponentModel.DataAnnotations" #> 4 | <#@ assembly name="System.Core" #> 5 | <#@ assembly name="System.Data.Entity" #> 6 | <#@ assembly name="System.Data.Linq" #> 7 | <#@ import namespace="System" #> 8 | <#@ import namespace="System.Collections" #> 9 | <#@ import namespace="System.Collections.Generic" #> 10 | <#@ import namespace="System.ComponentModel.DataAnnotations" #> 11 | <#@ import namespace="System.Data.Linq.Mapping" #> 12 | <#@ import namespace="System.Data.Objects.DataClasses" #> 13 | <#@ import namespace="System.Linq" #> 14 | <#@ import namespace="System.Reflection" #> 15 | <#@ import namespace="EnvDTE" #> 16 | <# 17 | Dim viewDataType = CType(Model.ViewDataType, CodeType) 18 | Dim mvcViewDataTypeGenericString As String = If(viewDataType IsNot Nothing, "(Of " & viewDataType.FullName & ")", String.Empty) 19 | Dim CPHCounter As Integer = 1 20 | #> 21 | <# 22 | If Model.IsContentPage Then 23 | #> 24 | <%@ Page Title="" Language="VB" MasterPageFile="~<#= Model.Layout #>" Inherits="System.Web.Mvc.ViewPage<#= mvcViewDataTypeGenericString #>" %> 25 | 26 | <# 27 | For Each cphid As String In Model.SectionNames 28 | If cphid.Equals("TitleContent", StringComparison.OrdinalIgnoreCase) Then 29 | #> 30 | 31 | <#= Model.ViewName #> 32 | 33 | 34 | <# 35 | CPHCounter += 1 36 | End If 37 | Next 38 | #> 39 | 40 | 41 |

<#= Model.ViewName #>

42 | 43 | <# 44 | Else 45 | #> 46 | <%@ Page Language="VB" Inherits="System.Web.Mvc.ViewPage<#= mvcViewDataTypeGenericString #>" %> 47 | 48 | 49 | 50 | 51 | <#= Model.ViewName #> 52 | 53 | 54 | <# 55 | PushIndent(" ") 56 | End If 57 | #> 58 |

Are you sure you want to delete this?

59 |
60 | <#= If(Model.ViewDataTypeName, String.Empty) #> 61 | <# 62 | For Each modelProp As ModelProperty In GetModelProperties(Model.ViewDataType, True) 63 | If (Not modelProp.IsPrimaryKey AndAlso Not modelProp.IsForeignKey) Then 64 | #> 65 | 66 |
<#= modelProp.Name #>
67 |
<%: <#= modelProp.ValueExpression #> %>
68 | <# 69 | End If 70 | Next 71 | #> 72 |
73 | <% Using Html.BeginForm() %> 74 |

75 | | 76 | <%: Html.ActionLink("Back to List", "Index") %> 77 |

78 | <% End Using %> 79 | 80 | <# 81 | ' The following code closes the asp:Content tag used in the case of a master page and the body and html tags in the case of a regular view page 82 | #> 83 | <# 84 | If Model.IsContentPage 85 | #> 86 |
87 | <# 88 | For Each cphid As String In Model.SectionNames 89 | If String.Compare(cphid, "TitleContent", StringComparison.OrdinalIgnoreCase) <> 0 AndAlso String.Compare(cphid, Model.PrimarySectionName, StringComparison.OrdinalIgnoreCase) <> 0 Then 90 | CPHCounter +=1 91 | #> 92 | 93 | 94 | 95 | <# 96 | End If 97 | Next 98 | #> 99 | <# 100 | Else If Not Model.IsContentPage Then 101 | ClearIndent() 102 | #> 103 | 104 | 105 | <# 106 | End If 107 | #> 108 | 109 | -------------------------------------------------------------------------------- /MvcScaffolding/Scaffolders/AspxView/Empty.cs.t4: -------------------------------------------------------------------------------- 1 | <#@ Template Language="C#" HostSpecific="True" Inherits="DynamicTransform" #> 2 | <#@ Output extension="aspx" #> 3 | <# var viewDataType = (EnvDTE.CodeType) Model.ViewDataType; #> 4 | <# 5 | string mvcViewDataTypeGenericString = (viewDataType != null) ? "<" + viewDataType.FullName + ">" : ""; 6 | int CPHCounter = 1; 7 | #> 8 | <# if(Model.IsContentPage) { #> 9 | <%@ Page Title="" Language="C#" MasterPageFile="~<#= Model.Layout #>" Inherits="System.Web.Mvc.ViewPage<#= mvcViewDataTypeGenericString #>" %> 10 | 11 | <# 12 | foreach(string cphid in Model.SectionNames) { 13 | if(cphid.Equals("TitleContent", StringComparison.OrdinalIgnoreCase)) { 14 | #> 15 | 16 | <#= Model.ViewName #> 17 | 18 | 19 | <# 20 | CPHCounter++; 21 | } 22 | } 23 | #> 24 | 25 | 26 |

<#= Model.ViewName #>

27 | 28 | <# 29 | } else { 30 | #> 31 | <%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<#= mvcViewDataTypeGenericString #>" %> 32 | 33 | 34 | 35 | 36 | <#= Model.ViewName #> 37 | 38 | 39 | <# 40 | PushIndent(" "); 41 | } 42 | #> 43 | <# 44 | if(!Model.IsContentPage) { 45 | #> 46 |
47 | 48 |
49 | <# 50 | } 51 | #> 52 | <# 53 | // The following code closes the asp:Content tag used in the case of a master page and the body and html tags in the case of a regular view page 54 | #> 55 | <# 56 | if(Model.IsContentPage) { 57 | #> 58 |
59 | <# 60 | foreach(string cphid in Model.SectionNames) { 61 | if(!cphid.Equals("TitleContent", StringComparison.OrdinalIgnoreCase) && !cphid.Equals(Model.PrimarySectionName, StringComparison.OrdinalIgnoreCase)) { 62 | CPHCounter++; 63 | #> 64 | 65 | 66 | 67 | <# 68 | } 69 | } 70 | #> 71 | <# 72 | } else if(!Model.IsContentPage) { 73 | ClearIndent(); 74 | #> 75 | 76 | 77 | <# 78 | } 79 | #> -------------------------------------------------------------------------------- /MvcScaffolding/Scaffolders/AspxView/Empty.vb.t4: -------------------------------------------------------------------------------- 1 | <#@ Template Language="VB" HostSpecific="True" Inherits="DynamicTransform" #> 2 | <#@ Output extension="aspx" #> 3 | <# 4 | Dim viewDataType = CType(Model.ViewDataType, EnvDTE.CodeType) 5 | Dim mvcViewDataTypeGenericString As String = If(viewDataType IsNot Nothing, "(Of " & viewDataType.FullName & ")", String.Empty) 6 | Dim CPHCounter As Integer = 1 7 | #> 8 | <# 9 | If Model.IsContentPage Then 10 | #> 11 | <%@ Page Title="" Language="VB" MasterPageFile="~<#= Model.Layout #>" Inherits="System.Web.Mvc.ViewPage<#= mvcViewDataTypeGenericString #>" %> 12 | 13 | <# 14 | For Each cphid As String In Model.SectionNames 15 | If cphid.Equals("TitleContent", StringComparison.OrdinalIgnoreCase) Then 16 | #> 17 | 18 | <#= Model.ViewName #> 19 | 20 | 21 | <# 22 | CPHCounter += 1 23 | End If 24 | Next 25 | #> 26 | 27 | 28 |

<#= Model.ViewName #>

29 | 30 | <# 31 | Else 32 | #> 33 | <%@ Page Language="VB" Inherits="System.Web.Mvc.ViewPage<#= mvcViewDataTypeGenericString #>" %> 34 | 35 | 36 | 37 | 38 | <#= Model.ViewName #> 39 | 40 | 41 | <# 42 | PushIndent(" ") 43 | End If 44 | #> 45 | <# 46 | If Not Model.IsContentPage Then 47 | #> 48 |
49 | 50 |
51 | <# 52 | End If 53 | #> 54 | <# 55 | ' The following code closes the asp:Content tag used in the case of a master page and the body and html tags in the case of a regular view page 56 | #> 57 | <# 58 | If Model.IsContentPage Then 59 | #> 60 |
61 | <# 62 | For Each cphid As String In Model.SectionNames 63 | If String.Compare(cphid, "TitleContent", StringComparison.OrdinalIgnoreCase) <> 0 AndAlso String.Compare(cphid, Model.PrimarySectionName, StringComparison.OrdinalIgnoreCase) <> 0 Then 64 | CPHCounter += 1 65 | #> 66 | 67 | 68 | 69 | <# 70 | End If 71 | Next 72 | #> 73 | <# 74 | Else If Not Model.IsContentPage Then 75 | ClearIndent() 76 | #> 77 | 78 | 79 | <# 80 | End If 81 | #> -------------------------------------------------------------------------------- /MvcScaffolding/Scaffolders/AspxView/MvcScaffolding.AspxView.ps1: -------------------------------------------------------------------------------- 1 | [T4Scaffolding.ViewScaffolder("ASPX", Description = "Adds an ASP.NET MVC view using the ASPX view engine", LayoutPageFilter = "*.master|*.master")][CmdletBinding()] 2 | param( 3 | [parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, Position = 0)][string]$Controller, 4 | [parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, Position = 1)][string]$ViewName, 5 | [string]$ModelType, 6 | [string]$Template = "Empty", 7 | [string]$Area, 8 | [alias("Layout")]$MasterPage = "", 9 | [alias("SectionNames")][string[]]$ContentPlaceholderIDs, 10 | [alias("PrimarySectionName")][string]$PrimaryContentPlaceholderID, 11 | [switch]$ReferenceScriptLibraries = $false, 12 | [string]$Project, 13 | [string]$CodeLanguage, 14 | [string[]]$TemplateFolders, 15 | [switch]$Force = $false 16 | ) 17 | 18 | # Populate masterpage-related args with defaults based on standard MVC 3 site template where not specified. 19 | # If you haven't passed a -MasterPage argument but it looks like you are using a standard master page, assume 20 | # you do want to use that master page. If you really don't want any master, explicitly pass -MasterPage $null. 21 | $defaultMasterPage = "/Views/Shared/Site.Master" 22 | if ($MasterPage -eq "") { 23 | $MasterPage = if (Get-ProjectItem $defaultMasterPage) { $defaultMasterPage } else { $null } 24 | } 25 | if (!$ContentPlaceholderIDs) { $ContentPlaceholderIDs = @("TitleContent", "MainContent") } 26 | if (!$PrimaryContentPlaceholderID) { $PrimaryContentPlaceholderID = "MainContent" } 27 | 28 | # In the case of view names with a leading underscore, this is a Razor convention that Aspx doesn't follow 29 | # so we just strip off any leading underscore 30 | if ($Template.StartsWith("_") -and ($Template.Length -gt 1)) { $Template = $Template.Substring(1) } 31 | if ($ViewName.StartsWith("_") -and ($ViewName.Length -gt 1)) { $ViewName = $ViewName.Substring(1) } 32 | 33 | # In the case of master page names with a leading tilde, strip it off, because the view templates 34 | # automatically prefix the master name with a tilde 35 | if ($MasterPage -and $MasterPage.StartsWith("~")) { 36 | $MasterPage = $MasterPage.Substring(1) 37 | } 38 | 39 | # Inherit all logic from MvcScaffolding.RazorView (merely override the templates) 40 | Scaffold MvcScaffolding.RazorView -Controller $Controller -ViewName $ViewName -ModelType $ModelType -Template $Template -Area $Area -Layout $MasterPage -SectionNames $ContentPlaceholderIDs -PrimarySectionName $PrimaryContentPlaceholderID -ReferenceScriptLibraries:$ReferenceScriptLibraries -Project $Project -CodeLanguage $CodeLanguage -OverrideTemplateFolders $TemplateFolders -Force:$Force -------------------------------------------------------------------------------- /MvcScaffolding/Scaffolders/Controller/MvcScaffolding.ControllerWithRepository.ps1: -------------------------------------------------------------------------------- 1 | [T4Scaffolding.ControllerScaffolder("Controller with read/write action and views, using repositories", HideInConsole = $true, Description = "Adds an ASP.NET MVC controller with views and data access code", SupportsModelType = $true, SupportsDataContextType = $true, SupportsViewScaffolder = $true)][CmdletBinding()] 2 | param( 3 | [parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)][string]$ControllerName, 4 | [string]$ModelType, 5 | [string]$Project, 6 | [string]$CodeLanguage, 7 | [string]$DbContextType, 8 | [string]$Area, 9 | [string]$ViewScaffolder = "View", 10 | [alias("MasterPage")]$Layout, 11 | [alias("ContentPlaceholderIDs")][string[]]$SectionNames, 12 | [alias("PrimaryContentPlaceholderID")][string]$PrimarySectionName, 13 | [switch]$ReferenceScriptLibraries = $false, 14 | [switch]$NoChildItems = $false, 15 | [string[]]$TemplateFolders, 16 | [switch]$Force = $false, 17 | [string]$ForceMode 18 | ) 19 | 20 | Scaffold MvcScaffolding.Controller ` 21 | -ControllerName $ControllerName ` 22 | -ModelType $ModelType ` 23 | -Project $Project ` 24 | -CodeLanguage $CodeLanguage ` 25 | -DbContextType $DbContextType ` 26 | -Area $Area ` 27 | -ViewScaffolder $ViewScaffolder ` 28 | -Layout $Layout ` 29 | -SectionNames $SectionNames ` 30 | -PrimarySectionName $PrimarySectionName ` 31 | -ReferenceScriptLibraries:$ReferenceScriptLibraries ` 32 | -NoChildItems:$NoChildItems ` 33 | -OverrideTemplateFolders $TemplateFolders ` 34 | -Force:$Force ` 35 | -ForceMode $ForceMode ` 36 | -Repository 37 | -------------------------------------------------------------------------------- /MvcScaffolding/Scaffolders/RazorView/Create.cs.t4: -------------------------------------------------------------------------------- 1 | <#@ Template Language="C#" HostSpecific="True" Inherits="DynamicTransform" #> 2 | <#@ Output extension="cshtml" #> 3 | <#@ assembly name="System.ComponentModel.DataAnnotations" #> 4 | <#@ assembly name="System.Core" #> 5 | <#@ assembly name="System.Data.Entity" #> 6 | <#@ assembly name="System.Data.Linq" #> 7 | <#@ import namespace="System" #> 8 | <#@ import namespace="System.Collections" #> 9 | <#@ import namespace="System.Collections.Generic" #> 10 | <#@ import namespace="System.ComponentModel.DataAnnotations" #> 11 | <#@ import namespace="System.Data.Linq.Mapping" #> 12 | <#@ import namespace="System.Data.Objects.DataClasses" #> 13 | <#@ import namespace="System.Linq" #> 14 | <#@ import namespace="System.Reflection" #> 15 | <# var viewDataType = (EnvDTE.CodeType) Model.ViewDataType; #> 16 | <# if(viewDataType != null) { #> 17 | @model <#= viewDataType.FullName #> 18 | 19 | <# } #> 20 | @{ 21 | ViewBag.Title = "<#= Model.ViewName #>"; 22 | <# 23 | if (!String.IsNullOrEmpty(Model.Layout)) { 24 | #> 25 | Layout = "<#= Model.Layout #>"; 26 | <# 27 | } 28 | #> 29 | } 30 | 31 |

<#= Model.ViewName #>

32 | 33 | <# if(Model.ReferenceScriptLibraries) { #> 34 | 35 | 36 | 37 | <# } #> 38 | @using (Html.BeginForm()) { 39 | @Html.ValidationSummary(true) 40 |
41 | <#= Model.ViewDataTypeName ?? String.Empty #> 42 | 43 | @Html.Partial("_CreateOrEdit", Model) 44 | 45 |

46 | 47 |

48 |
49 | } 50 | 51 |
52 | @Html.ActionLink("Back to List", "Index") 53 |
54 | 55 | -------------------------------------------------------------------------------- /MvcScaffolding/Scaffolders/RazorView/Create.vb.t4: -------------------------------------------------------------------------------- 1 | <#@ Template Language="VB" HostSpecific="True" Inherits="DynamicTransform" #> 2 | <#@ Output extension="vbhtml" #> 3 | <#@ assembly name="System.ComponentModel.DataAnnotations" #> 4 | <#@ assembly name="System.Core" #> 5 | <#@ assembly name="System.Data.Entity" #> 6 | <#@ assembly name="System.Data.Linq" #> 7 | <#@ import namespace="System" #> 8 | <#@ import namespace="System.Collections" #> 9 | <#@ import namespace="System.Collections.Generic" #> 10 | <#@ import namespace="System.ComponentModel.DataAnnotations" #> 11 | <#@ import namespace="System.Data.Linq.Mapping" #> 12 | <#@ import namespace="System.Data.Objects.DataClasses" #> 13 | <#@ import namespace="System.Linq" #> 14 | <#@ import namespace="System.Reflection" #> 15 | <#@ import namespace="EnvDTE" #> 16 | <# Dim viewDataType = CType(Model.ViewDataType, CodeType) #> 17 | <# If viewDataType IsNot Nothing #> 18 | @ModelType <#= viewDataType.FullName #> 19 | 20 | <# End If #> 21 | @Code 22 | ViewData("Title") = "<#= Model.ViewName #>" 23 | <# If Not String.IsNullOrEmpty(Model.Layout) #> 24 | Layout = "<#= Model.Layout #>" 25 | <# End If #> 26 | End Code 27 | 28 |

<#= Model.ViewName #>

29 | 30 | <# If Model.ReferenceScriptLibraries Then #> 31 | 32 | 33 | 34 | <# End If #> 35 | @Using Html.BeginForm() 36 | @Html.ValidationSummary(True) 37 | @
38 | <#= If(Model.ViewDataTypeName, String.Empty) #> 39 | 40 | @Html.Partial("_CreateOrEdit", Model) 41 |

42 | 43 |

44 |
45 | End Using 46 | 47 |
48 | @Html.ActionLink("Back to List", "Index") 49 |
50 | 51 | -------------------------------------------------------------------------------- /MvcScaffolding/Scaffolders/RazorView/Delete.cs.t4: -------------------------------------------------------------------------------- 1 | <#@ Template Language="C#" HostSpecific="True" Inherits="DynamicTransform" #> 2 | <#@ Output extension="cshtml" #> 3 | <#@ assembly name="System.ComponentModel.DataAnnotations" #> 4 | <#@ assembly name="System.Core" #> 5 | <#@ assembly name="System.Data.Entity" #> 6 | <#@ assembly name="System.Data.Linq" #> 7 | <#@ import namespace="System" #> 8 | <#@ import namespace="System.Collections" #> 9 | <#@ import namespace="System.Collections.Generic" #> 10 | <#@ import namespace="System.ComponentModel.DataAnnotations" #> 11 | <#@ import namespace="System.Data.Linq.Mapping" #> 12 | <#@ import namespace="System.Data.Objects.DataClasses" #> 13 | <#@ import namespace="System.Linq" #> 14 | <#@ import namespace="System.Reflection" #> 15 | <# var viewDataType = (EnvDTE.CodeType) Model.ViewDataType; #> 16 | <# if(viewDataType != null) { #> 17 | @model <#= viewDataType.FullName #> 18 | 19 | <# } #> 20 | @{ 21 | ViewBag.Title = "<#= Model.ViewName #>"; 22 | <# if (!String.IsNullOrEmpty(Model.Layout)) { #> 23 | Layout = "<#= Model.Layout #>"; 24 | <# } #> 25 | } 26 | 27 |

<#= Model.ViewName #>

28 | 29 |

Are you sure you want to delete this?

30 |
31 | <#= Model.ViewDataTypeName ?? String.Empty #> 32 | <# 33 | foreach (ModelProperty property in GetModelProperties(Model.ViewDataType, true)) { 34 | if (!property.IsPrimaryKey && !property.IsForeignKey) { 35 | #> 36 | 37 |
<#= property.Name #>
38 |
@<#= property.ValueExpression #>
39 | <# 40 | } 41 | } 42 | #> 43 |
44 | @using (Html.BeginForm()) { 45 |

46 | | 47 | @Html.ActionLink("Back to List", "Index") 48 |

49 | } 50 | 51 | -------------------------------------------------------------------------------- /MvcScaffolding/Scaffolders/RazorView/Delete.vb.t4: -------------------------------------------------------------------------------- 1 | <#@ Template Language="VB" HostSpecific="True" Inherits="DynamicTransform" #> 2 | <#@ Output extension="vbhtml" #> 3 | <#@ assembly name="System.ComponentModel.DataAnnotations" #> 4 | <#@ assembly name="System.Core" #> 5 | <#@ assembly name="System.Data.Entity" #> 6 | <#@ assembly name="System.Data.Linq" #> 7 | <#@ import namespace="System" #> 8 | <#@ import namespace="System.Collections" #> 9 | <#@ import namespace="System.Collections.Generic" #> 10 | <#@ import namespace="System.ComponentModel.DataAnnotations" #> 11 | <#@ import namespace="System.Data.Linq.Mapping" #> 12 | <#@ import namespace="System.Data.Objects.DataClasses" #> 13 | <#@ import namespace="System.Linq" #> 14 | <#@ import namespace="System.Reflection" #> 15 | <#@ import namespace="EnvDTE" #> 16 | <# Dim viewDataType = CType(Model.ViewDataType, CodeType) #> 17 | <# If viewDataType IsNot Nothing #> 18 | @ModelType <#= viewDataType.FullName #> 19 | 20 | <# End If #> 21 | @Code 22 | ViewData("Title") = "<#= Model.ViewName #>" 23 | <# If Not String.IsNullOrEmpty(Model.Layout) #> 24 | Layout = "<#= Model.Layout #>" 25 | <# End If #> 26 | End Code 27 | 28 |

<#= Model.ViewName #>

29 | 30 |

Are you sure you want to delete this?

31 |
32 | <#= If(Model.ViewDataTypeName, String.Empty) #> 33 | <# 34 | For Each modelProp As ModelProperty In GetModelProperties(Model.ViewDataType, True) 35 | If (Not modelProp.IsPrimaryKey AndAlso Not modelProp.IsForeignKey) Then 36 | #> 37 | 38 |
<#= modelProp.Name #>
39 |
@<#= modelProp.ValueExpression #>
40 | <# 41 | End If 42 | Next 43 | #> 44 |
45 | 46 | @Using Html.BeginForm() 47 | @

48 | | 49 | @Html.ActionLink("Back to List", "Index") 50 |

51 | End Using 52 | 53 | -------------------------------------------------------------------------------- /MvcScaffolding/Scaffolders/RazorView/Details.cs.t4: -------------------------------------------------------------------------------- 1 | <#@ Template Language="C#" HostSpecific="True" Inherits="DynamicTransform" #> 2 | <#@ Output extension="cshtml" #> 3 | <#@ assembly name="System.ComponentModel.DataAnnotations" #> 4 | <#@ assembly name="System.Core" #> 5 | <#@ assembly name="System.Data.Entity" #> 6 | <#@ assembly name="System.Data.Linq" #> 7 | <#@ import namespace="System" #> 8 | <#@ import namespace="System.Collections" #> 9 | <#@ import namespace="System.Collections.Generic" #> 10 | <#@ import namespace="System.ComponentModel.DataAnnotations" #> 11 | <#@ import namespace="System.Data.Linq.Mapping" #> 12 | <#@ import namespace="System.Data.Objects.DataClasses" #> 13 | <#@ import namespace="System.Linq" #> 14 | <#@ import namespace="System.Reflection" #> 15 | <# var viewDataType = (EnvDTE.CodeType) Model.ViewDataType; #> 16 | <# if(viewDataType != null) { #> 17 | @model <#= viewDataType.FullName #> 18 | 19 | <# } #> 20 | @{ 21 | ViewBag.Title = "<#= Model.ViewName #>"; 22 | <# if (!String.IsNullOrEmpty(Model.Layout)) { #> 23 | Layout = "<#= Model.Layout #>"; 24 | <# } #> 25 | } 26 | 27 |

<#= Model.ViewName #>

28 | 29 |
30 | <#= Model.ViewDataTypeName ?? String.Empty #> 31 | <# 32 | foreach (ModelProperty property in GetModelProperties(Model.ViewDataType, true)) { 33 | if (!property.IsPrimaryKey && !property.IsForeignKey) { 34 | #> 35 | 36 |
<#= property.Name #>
37 |
@<#= property.ValueExpression #>
38 | <# 39 | } 40 | } 41 | #> 42 |
43 |

44 | <# if (!String.IsNullOrEmpty(Model.PrimaryKeyName)) { #> 45 | @Html.ActionLink("Edit", "Edit", new { id=Model.<#= Model.PrimaryKeyName #> }) | 46 | @Html.ActionLink("Back to List", "Index") 47 | <# } else { #> 48 | @Html.ActionLink("Edit", "Edit", new { /* id=Model.PrimaryKey */ }) | 49 | @Html.ActionLink("Back to List", "Index") 50 | <# } #> 51 |

52 | 53 | -------------------------------------------------------------------------------- /MvcScaffolding/Scaffolders/RazorView/Details.vb.t4: -------------------------------------------------------------------------------- 1 | <#@ Template Language="VB" HostSpecific="True" Inherits="DynamicTransform" #> 2 | <#@ Output extension="vbhtml" #> 3 | <#@ assembly name="System.ComponentModel.DataAnnotations" #> 4 | <#@ assembly name="System.Core" #> 5 | <#@ assembly name="System.Data.Entity" #> 6 | <#@ assembly name="System.Data.Linq" #> 7 | <#@ import namespace="System" #> 8 | <#@ import namespace="System.Collections" #> 9 | <#@ import namespace="System.Collections.Generic" #> 10 | <#@ import namespace="System.ComponentModel.DataAnnotations" #> 11 | <#@ import namespace="System.Data.Linq.Mapping" #> 12 | <#@ import namespace="System.Data.Objects.DataClasses" #> 13 | <#@ import namespace="System.Linq" #> 14 | <#@ import namespace="System.Reflection" #> 15 | <#@ import namespace="EnvDTE" #> 16 | <# Dim viewDataType = CType(Model.ViewDataType, CodeType) #> 17 | <# If viewDataType IsNot Nothing #> 18 | @ModelType <#= viewDataType.FullName #> 19 | 20 | <# End If #> 21 | @Code 22 | ViewData("Title") = "<#= Model.ViewName #>" 23 | <# If Not String.IsNullOrEmpty(Model.Layout) #> 24 | Layout = "<#= Model.Layout #>" 25 | <# End If #> 26 | End Code 27 | 28 |

<#= Model.ViewName #>

29 | 30 |
31 | <#= If(Model.ViewDataTypeName, String.Empty) #> 32 | <# 33 | For Each modelProp As ModelProperty In GetModelProperties(Model.ViewDataType, True) 34 | If (Not modelProp.IsPrimaryKey AndAlso Not modelProp.IsForeignKey) Then 35 | #> 36 | 37 |
<#= modelProp.Name #>
38 |
@<#= modelProp.ValueExpression #>
39 | <# 40 | End If 41 | Next 42 | #> 43 |
44 | 45 |

46 | <# If Not String.IsNullOrEmpty(Model.PrimaryKeyName) Then #> 47 | @Html.ActionLink("Edit", "Edit", New With {.id = Model.<#= Model.PrimaryKeyName #>}) | 48 | @Html.ActionLink("Back to List", "Index") 49 | <# Else #> 50 | @*@Html.ActionLink("Edit", "Edit", New With {.id = Model.PrimaryKey}) |*@ 51 | @Html.ActionLink("Back to List", "Index") 52 | <# End If #> 53 |

54 | 55 | -------------------------------------------------------------------------------- /MvcScaffolding/Scaffolders/RazorView/Edit.cs.t4: -------------------------------------------------------------------------------- 1 | <#@ Template Language="C#" HostSpecific="True" Inherits="DynamicTransform" #> 2 | <#@ Output extension="cshtml" #> 3 | <#@ assembly name="System.ComponentModel.DataAnnotations" #> 4 | <#@ assembly name="System.Core" #> 5 | <#@ assembly name="System.Data.Entity" #> 6 | <#@ assembly name="System.Data.Linq" #> 7 | <#@ import namespace="System" #> 8 | <#@ import namespace="System.Collections" #> 9 | <#@ import namespace="System.Collections.Generic" #> 10 | <#@ import namespace="System.ComponentModel.DataAnnotations" #> 11 | <#@ import namespace="System.Data.Linq.Mapping" #> 12 | <#@ import namespace="System.Data.Objects.DataClasses" #> 13 | <#@ import namespace="System.Linq" #> 14 | <#@ import namespace="System.Reflection" #> 15 | <# var viewDataType = (EnvDTE.CodeType) Model.ViewDataType; #> 16 | <# if(viewDataType != null) { #> 17 | @model <#= viewDataType.FullName #> 18 | 19 | <# } #> 20 | @{ 21 | ViewBag.Title = "<#= Model.ViewName #>"; 22 | <# if (!String.IsNullOrEmpty(Model.Layout)) { #> 23 | Layout = "<#= Model.Layout #>"; 24 | <# } #> 25 | } 26 | 27 |

<#= Model.ViewName #>

28 | 29 | <# if(Model.ReferenceScriptLibraries) { #> 30 | 31 | 32 | 33 | <# } #> 34 | @using (Html.BeginForm()) { 35 | @Html.ValidationSummary(true) 36 |
37 | <#= Model.ViewDataTypeName ?? String.Empty #> 38 | 39 | <# foreach (ModelProperty property in GetModelProperties(viewDataType, false).Where(x => x.IsPrimaryKey)) { #> 40 | @Html.HiddenFor(model => model.<#= property.Name #>) 41 | <# } #> 42 | @Html.Partial("_CreateOrEdit", Model) 43 | 44 |

45 | 46 |

47 |
48 | } 49 | 50 |
51 | @Html.ActionLink("Back to List", "Index") 52 |
-------------------------------------------------------------------------------- /MvcScaffolding/Scaffolders/RazorView/Edit.vb.t4: -------------------------------------------------------------------------------- 1 | <#@ Template Language="VB" HostSpecific="True" Inherits="DynamicTransform" #> 2 | <#@ Output extension="vbhtml" #> 3 | <#@ assembly name="System.ComponentModel.DataAnnotations" #> 4 | <#@ assembly name="System.Core" #> 5 | <#@ assembly name="System.Data.Entity" #> 6 | <#@ assembly name="System.Data.Linq" #> 7 | <#@ import namespace="System" #> 8 | <#@ import namespace="System.Collections" #> 9 | <#@ import namespace="System.Collections.Generic" #> 10 | <#@ import namespace="System.ComponentModel.DataAnnotations" #> 11 | <#@ import namespace="System.Data.Linq.Mapping" #> 12 | <#@ import namespace="System.Data.Objects.DataClasses" #> 13 | <#@ import namespace="System.Linq" #> 14 | <#@ import namespace="System.Reflection" #> 15 | <#@ import namespace="EnvDTE" #> 16 | <# Dim viewDataType = CType(Model.ViewDataType, CodeType) #> 17 | <# If viewDataType IsNot Nothing #> 18 | @ModelType <#= viewDataType.FullName #> 19 | 20 | <# End If #> 21 | @Code 22 | ViewData("Title") = "<#= Model.ViewName #>" 23 | <# If Not String.IsNullOrEmpty(Model.Layout) #> 24 | Layout = "<#= Model.Layout #>" 25 | <# End If #> 26 | End Code 27 | 28 |

<#= Model.ViewName #>

29 | 30 | <# If Model.ReferenceScriptLibraries Then #> 31 | 32 | 33 | 34 | <# End If #> 35 | @Using Html.BeginForm() 36 | @Html.ValidationSummary(True) 37 | @
38 | <#= If(Model.ViewDataTypeName, String.Empty) #> 39 | 40 | <# For Each modelProp As ModelProperty In GetModelProperties(viewDataType, False).Where(Function(x) x.IsPrimaryKey) #> 41 | @Html.HiddenFor(Function(model) model.<#= modelProp.Name #>) 42 | <# Next #> 43 | @Html.Partial("_CreateOrEdit", Model) 44 |

45 | 46 |

47 |
48 | End Using 49 | 50 |
51 | @Html.ActionLink("Back to List", "Index") 52 |
53 | 54 | -------------------------------------------------------------------------------- /MvcScaffolding/Scaffolders/RazorView/Empty.cs.t4: -------------------------------------------------------------------------------- 1 | <#@ Template Language="C#" HostSpecific="True" Inherits="DynamicTransform" #> 2 | <#@ Output extension="cshtml" #> 3 | <# var viewDataType = (EnvDTE.CodeType) Model.ViewDataType; #> 4 | <# if(viewDataType != null) { #> 5 | @model <#= viewDataType.FullName #> 6 | 7 | <# } #> 8 | @{ 9 | ViewBag.Title = "<#= Model.ViewName #>"; 10 | <# if (!String.IsNullOrEmpty(Model.Layout)) { #> 11 | Layout = "<#= Model.Layout #>"; 12 | <# } #> 13 | } 14 | 15 |

<#= Model.ViewName #>

-------------------------------------------------------------------------------- /MvcScaffolding/Scaffolders/RazorView/Empty.vb.t4: -------------------------------------------------------------------------------- 1 | <#@ Template Language="VB" HostSpecific="True" Inherits="DynamicTransform" #> 2 | <#@ Output extension="vbhtml" #> 3 | <# Dim viewDataType = CType(Model.ViewDataType, EnvDTE.CodeType) #> 4 | <# If viewDataType IsNot Nothing Then #> 5 | @ModelType <#= viewDataType.FullName #> 6 | 7 | <# End If #> 8 | @Code 9 | ViewData("Title") = "<#= Model.ViewName #>" 10 | <# If Not String.IsNullOrEmpty(Model.Layout) #> 11 | Layout = "<#= Model.Layout #>" 12 | <# End If #> 13 | End Code 14 | 15 |

<#= Model.ViewName #>

-------------------------------------------------------------------------------- /MvcScaffolding/Scaffolders/RazorView/Index.cs.t4: -------------------------------------------------------------------------------- 1 | <#@ Template Language="C#" HostSpecific="True" Inherits="DynamicTransform" #> 2 | <#@ Output extension="cshtml" #> 3 | <#@ assembly name="System.ComponentModel.DataAnnotations" #> 4 | <#@ assembly name="System.Core" #> 5 | <#@ assembly name="System.Data.Entity" #> 6 | <#@ assembly name="System.Data.Linq" #> 7 | <#@ import namespace="System" #> 8 | <#@ import namespace="System.Collections" #> 9 | <#@ import namespace="System.Collections.Generic" #> 10 | <#@ import namespace="System.ComponentModel.DataAnnotations" #> 11 | <#@ import namespace="System.Data.Linq.Mapping" #> 12 | <#@ import namespace="System.Data.Objects.DataClasses" #> 13 | <#@ import namespace="System.Linq" #> 14 | <#@ import namespace="System.Reflection" #> 15 | <# var viewDataType = (EnvDTE.CodeType) Model.ViewDataType; #> 16 | <# if(viewDataType != null) { #> 17 | @model IEnumerable<<#= viewDataType.FullName #>> 18 | 19 | <# } #> 20 | @{ 21 | ViewBag.Title = "<#= Model.ViewName #>"; 22 | <# if (!String.IsNullOrEmpty(Model.Layout)) { #> 23 | Layout = "<#= Model.Layout #>"; 24 | <# } #> 25 | } 26 | 27 |

<#= Model.ViewName #>

28 | 29 |

30 | @Html.ActionLink("Create New", "Create") 31 |

32 | 33 | 34 | 35 | <# 36 | List properties = GetModelProperties(Model.ViewDataType, true); 37 | foreach (ModelProperty property in properties) { 38 | if (!property.IsPrimaryKey && !property.IsForeignKey) { 39 | #> 40 | 43 | <# 44 | } 45 | } 46 | #> 47 | 48 | 49 | @foreach (var item in Model) { 50 | 51 | <# if (!String.IsNullOrEmpty(Model.PrimaryKeyName)) { #> 52 | 57 | <# } else { #> 58 | 63 | <# } #> 64 | <# 65 | foreach (ModelProperty property in properties) { 66 | if (!property.IsPrimaryKey && !property.IsForeignKey) { 67 | #> 68 | 71 | <# 72 | } 73 | } 74 | #> 75 | 76 | } 77 | 78 |
41 | <#= property.Name #> 42 |
53 | @Html.ActionLink("Edit", "Edit", new { id=item.<#= Model.PrimaryKeyName #> }) | 54 | @Html.ActionLink("Details", "Details", new { id=item.<#= Model.PrimaryKeyName #> }) | 55 | @Html.ActionLink("Delete", "Delete", new { id=item.<#= Model.PrimaryKeyName #> }) 56 | 59 | @Html.ActionLink("Edit", "Edit", new { /* id=item.PrimaryKey */ }) | 60 | @Html.ActionLink("Details", "Details", new { /* id=item.PrimaryKey */ }) | 61 | @Html.ActionLink("Delete", "Delete", new { /* id=item.PrimaryKey */ }) 62 | 69 | @<#= property.ValueExpression.Replace("Model.", "item.") #> 70 |
79 | 80 | -------------------------------------------------------------------------------- /MvcScaffolding/Scaffolders/RazorView/Index.vb.t4: -------------------------------------------------------------------------------- 1 | <#@ Template Language="VB" HostSpecific="True" Inherits="DynamicTransform" #> 2 | <#@ Output extension="vbhtml" #> 3 | <#@ assembly name="System.ComponentModel.DataAnnotations" #> 4 | <#@ assembly name="System.Core" #> 5 | <#@ assembly name="System.Data.Entity" #> 6 | <#@ assembly name="System.Data.Linq" #> 7 | <#@ import namespace="System" #> 8 | <#@ import namespace="System.Collections" #> 9 | <#@ import namespace="System.Collections.Generic" #> 10 | <#@ import namespace="System.ComponentModel.DataAnnotations" #> 11 | <#@ import namespace="System.Data.Linq.Mapping" #> 12 | <#@ import namespace="System.Data.Objects.DataClasses" #> 13 | <#@ import namespace="System.Linq" #> 14 | <#@ import namespace="System.Reflection" #> 15 | <#@ import namespace="EnvDTE" #> 16 | <# Dim viewDataType = CType(Model.ViewDataType, CodeType) #> 17 | <# If viewDataType IsNot Nothing #> 18 | @ModelType IEnumerable(Of <#= viewDataType.FullName #>) 19 | 20 | <# End If #> 21 | @Code 22 | ViewData("Title") = "<#= Model.ViewName #>" 23 | <# 24 | If Not String.IsNullOrEmpty(Model.Layout) 25 | #> 26 | Layout = "<#= Model.Layout #>" 27 | <# 28 | End If 29 | #> 30 | End Code 31 | 32 |

<#= Model.ViewName #>

33 | 34 |

35 | @Html.ActionLink("Create New", "Create") 36 |

37 | 38 | 39 | 40 | <# 41 | Dim properties As List(Of ModelProperty) = GetModelProperties(Model.ViewDataType, True) 42 | For Each modelProp As ModelProperty In properties 43 | If (Not modelProp.IsPrimaryKey AndAlso Not modelProp.IsForeignKey) Then 44 | #> 45 | 48 | <# 49 | End If 50 | Next 51 | #> 52 | 53 | 54 | @For Each item In Model 55 | Dim itemValue = item 56 | @ 57 | <# If Not String.IsNullOrEmpty(Model.PrimaryKeyName) Then #> 58 | 63 | <# 64 | Else 65 | #> 66 | 71 | <# 72 | End If 73 | 74 | For Each modelProp As ModelProperty In properties 75 | If (Not modelProp.IsPrimaryKey AndAlso Not modelProp.IsForeignKey) Then 76 | #> 77 | 80 | <# 81 | End If 82 | Next 83 | #> 84 | 85 | Next 86 | 87 |
46 | <#= modelProp.Name #> 47 |
59 | @Html.ActionLink("Edit", "Edit", New With {.id = itemValue.<#= Model.PrimaryKeyName #>}) | 60 | @Html.ActionLink("Details", "Details", New With {.id = itemValue.<#= Model.PrimaryKeyName #>}) | 61 | @Html.ActionLink("Delete", "Delete", New With {.id = itemValue.<#= Model.PrimaryKeyName #>}) 62 | 67 | @*@Html.ActionLink("Edit", "Edit", New With {.id = itemValue.PrimaryKey}) | 68 | @Html.ActionLink("Details", "Details", New With {.id = itemValue.PrimaryKey}) | 69 | @Html.ActionLink("Delete", "Delete", New With {.id = itemValue.PrimaryKey})*@ 70 | 78 | @<#= modelProp.ValueExpression.Replace("Model.", "itemValue.") #> 79 |
88 | -------------------------------------------------------------------------------- /MvcScaffolding/Scaffolders/RazorView/MvcScaffolding.RazorView.ps1: -------------------------------------------------------------------------------- 1 | [T4Scaffolding.ViewScaffolder("Razor", Description = "Adds an ASP.NET MVC view using the Razor view engine", IsRazorType = $true, LayoutPageFilter = "*.cshtml,*.vbhtml|*.cshtml,*.vbhtml")][CmdletBinding()] 2 | param( 3 | [parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, Position = 0)][string]$Controller, 4 | [parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, Position = 1)][string]$ViewName, 5 | [string]$ModelType, 6 | [string]$Template = "Empty", 7 | [string]$Area, 8 | [alias("MasterPage")]$Layout, # If not set, we'll use the default layout 9 | [string[]]$SectionNames, 10 | [string]$PrimarySectionName, 11 | [switch]$ReferenceScriptLibraries = $false, 12 | [string]$Project, 13 | [string]$CodeLanguage, 14 | [string[]]$TemplateFolders, 15 | [switch]$Force = $false 16 | ) 17 | 18 | # Ensure we have a controller name, plus a model type if specified 19 | if ($ModelType) { 20 | $foundModelType = Get-ProjectType $ModelType -Project $Project 21 | if (!$foundModelType) { return } 22 | $primaryKeyName = [string](Get-PrimaryKey $foundModelType.FullName -Project $Project) 23 | } 24 | 25 | # Decide where to put the output 26 | $outputFolderName = Join-Path Views $Controller 27 | if ($Area) { 28 | # We don't create areas here, so just ensure that if you specify one, it already exists 29 | $areaPath = Join-Path Areas $Area 30 | if (-not (Get-ProjectItem $areaPath -Project $Project)) { 31 | Write-Error "Cannot find area '$Area'. Make sure it exists already." 32 | return 33 | } 34 | $outputFolderName = Join-Path $areaPath $outputFolderName 35 | } 36 | 37 | 38 | if ($foundModelType) { $relatedEntities = [Array](Get-RelatedEntities $foundModelType.FullName -Project $project) } 39 | if (!$relatedEntities) { $relatedEntities = @() } 40 | 41 | # Render the T4 template, adding the output to the Visual Studio project 42 | $outputPath = Join-Path $outputFolderName $ViewName 43 | Add-ProjectItemViaTemplate $outputPath -Template $Template -Model @{ 44 | IsContentPage = [bool]$Layout; 45 | Layout = $Layout; 46 | SectionNames = $SectionNames; 47 | PrimarySectionName = $PrimarySectionName; 48 | ReferenceScriptLibraries = $ReferenceScriptLibraries.ToBool(); 49 | ViewName = $ViewName; 50 | PrimaryKeyName = $primaryKeyName; 51 | ViewDataType = [MarshalByRefObject]$foundModelType; 52 | ViewDataTypeName = $foundModelType.Name; 53 | RelatedEntities = $relatedEntities; 54 | } -SuccessMessage "Added $ViewName view at '{0}'" -TemplateFolders $TemplateFolders -Project $Project -CodeLanguage $CodeLanguage -Force:$Force 55 | -------------------------------------------------------------------------------- /MvcScaffolding/Scaffolders/RazorView/_CreateOrEdit.cs.t4: -------------------------------------------------------------------------------- 1 | <#@ Template Language="C#" HostSpecific="True" Inherits="DynamicTransform" #> 2 | <#@ Output extension="cshtml" #> 3 | <#@ assembly name="System.ComponentModel.DataAnnotations" #> 4 | <#@ assembly name="System.Core" #> 5 | <#@ assembly name="System.Data.Entity" #> 6 | <#@ assembly name="System.Data.Linq" #> 7 | <#@ import namespace="System" #> 8 | <#@ import namespace="System.Collections" #> 9 | <#@ import namespace="System.Collections.Generic" #> 10 | <#@ import namespace="System.ComponentModel.DataAnnotations" #> 11 | <#@ import namespace="System.Data.Linq.Mapping" #> 12 | <#@ import namespace="System.Data.Objects.DataClasses" #> 13 | <#@ import namespace="System.Linq" #> 14 | <#@ import namespace="System.Reflection" #> 15 | <# var viewDataType = (EnvDTE.CodeType) Model.ViewDataType; #> 16 | <# if(viewDataType != null) { #> 17 | @model <#= viewDataType.FullName #> 18 | 19 | <# } #> 20 | @* This partial view defines form fields that will appear when creating and editing entities *@ 21 | 22 | <# 23 | foreach (ModelProperty property in GetModelProperties(Model.ViewDataType, false)) { 24 | if (!property.IsPrimaryKey && !property.IsForeignKey && !property.IsReadOnly) { 25 | #> 26 |
27 | @Html.LabelFor(model => model.<#= property.Name #>) 28 |
29 |
30 | @Html.EditorFor(model => model.<#= property.Name #>) 31 | @Html.ValidationMessageFor(model => model.<#= property.Name #>) 32 |
33 | 34 | <# 35 | } 36 | } 37 | #> 38 | <# 39 | foreach (RelatedEntityInfo relation in ParentRelations) { 40 | #> 41 |
42 | <#= relation.RelationName #> 43 |
44 |
45 | @Html.DropDownListFor(model => model.<#= relation.RelationProperty.Name #>, ((IEnumerable<<#= relation.RelatedEntityType.FullName #>>)ViewBag.Possible<#= relation.RelationNamePlural #>).Select(option => new SelectListItem { 46 | Text = <#= GetValueExpression("option", relation.RelatedEntityType) #>, 47 | Value = option.<#= relation.RelatedEntityPrimaryKeyName #>.ToString(), 48 | Selected = (Model != null) && (option.<#= relation.RelatedEntityPrimaryKeyName #> == Model.<#= relation.RelationProperty.Name #>) 49 | }), "Choose...") 50 | @Html.ValidationMessageFor(model => model.<#= relation.RelationProperty.Name #>) 51 |
52 | <# 53 | } 54 | #> -------------------------------------------------------------------------------- /MvcScaffolding/Scaffolders/RazorView/_CreateOrEdit.vb.t4: -------------------------------------------------------------------------------- 1 | <#@ Template Language="VB" HostSpecific="True" Inherits="DynamicTransform" #> 2 | <#@ Output extension="vbhtml" #> 3 | <#@ assembly name="System.ComponentModel.DataAnnotations" #> 4 | <#@ assembly name="System.Core" #> 5 | <#@ assembly name="System.Data.Entity" #> 6 | <#@ assembly name="System.Data.Linq" #> 7 | <#@ import namespace="System" #> 8 | <#@ import namespace="System.Collections" #> 9 | <#@ import namespace="System.Collections.Generic" #> 10 | <#@ import namespace="System.ComponentModel.DataAnnotations" #> 11 | <#@ import namespace="System.Data.Linq.Mapping" #> 12 | <#@ import namespace="System.Data.Objects.DataClasses" #> 13 | <#@ import namespace="System.Linq" #> 14 | <#@ import namespace="System.Reflection" #> 15 | <#@ import namespace="EnvDTE" #> 16 | <# Dim viewDataType = CType(Model.ViewDataType, CodeType) #> 17 | <# If viewDataType IsNot Nothing #> 18 | @ModelType <#= viewDataType.FullName #> 19 | 20 | <# End If #> 21 | @* This partial view defines form fields that will appear when creating and editing entities *@ 22 | 23 | <# 24 | For Each modelProp As ModelProperty In GetModelProperties(Model.ViewDataType, False) 25 | If (Not modelProp.IsPrimaryKey) AndAlso (Not modelProp.IsForeignKey) AndAlso (Not modelProp.IsReadOnly) Then 26 | #> 27 |
28 | @Html.LabelFor(Function(model) model.<#= modelProp.Name #>) 29 |
30 |
31 | @Html.EditorFor(Function(model) model.<#= modelProp.Name #>) 32 | @Html.ValidationMessageFor(Function(model) model.<#= modelProp.Name #>) 33 |
34 | 35 | <# 36 | End If 37 | Next 38 | #> 39 | <# For Each relation As RelatedEntityInfo In ParentRelations #> 40 |
41 | <#= relation.RelationName #> 42 |
43 |
44 | @Html.DropDownListFor(Function(model) model.<#= relation.RelationProperty.Name #>, CType(ViewBag.Possible<#= relation.RelationNamePlural #>, IEnumerable(Of <#= relation.RelatedEntityType.FullName #>)).Select(Function(optionValue) New SelectListItem() With { _ 45 | .Text = <#= GetValueExpression("optionValue", relation.RelatedEntityType) #>, _ 46 | .Value = optionValue.<#= relation.RelatedEntityPrimaryKeyName #>.ToString(), _ 47 | .Selected = (Model IsNot Nothing) AndAlso (optionValue.<#= relation.RelatedEntityPrimaryKeyName #>.Equals(Model.<#= relation.RelationProperty.Name #>)) _ 48 | }), "Choose...") 49 | @Html.ValidationMessageFor(Function(model) model.<#= relation.RelationProperty.Name #>) 50 |
51 | <# Next #> -------------------------------------------------------------------------------- /MvcScaffolding/Scaffolders/Views/MvcScaffolding.Views.ps1: -------------------------------------------------------------------------------- 1 | [T4Scaffolding.Scaffolder(Description = "Adds ASP.NET MVC views for Create/Read/Update/Delete/Index scenarios")][CmdletBinding()] 2 | param( 3 | [parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, Position = 0)][string]$Controller, 4 | [string]$ModelType, 5 | [string]$Area, 6 | [alias("MasterPage")]$Layout = "", # If not set, we'll use the default layout 7 | [alias("ContentPlaceholderIDs")][string[]]$SectionNames, 8 | [alias("PrimaryContentPlaceholderID")][string]$PrimarySectionName, 9 | [switch]$ReferenceScriptLibraries = $false, 10 | [string]$Project, 11 | [string]$CodeLanguage, 12 | [string[]]$TemplateFolders, 13 | [string]$ViewScaffolder = "View", 14 | [switch]$Force = $false 15 | ) 16 | 17 | @("Create", "Edit", "Delete", "Details", "Index", "_CreateOrEdit") | %{ 18 | Scaffold $ViewScaffolder -Controller $Controller -ViewName $_ -ModelType $ModelType -Template $_ -Area $Area -Layout $Layout -SectionNames $SectionNames -PrimarySectionName $PrimarySectionName -ReferenceScriptLibraries:$ReferenceScriptLibraries -Project $Project -CodeLanguage $CodeLanguage -OverrideTemplateFolders $TemplateFolders -Force:$Force 19 | } -------------------------------------------------------------------------------- /MvcScaffolding/init.ps1: -------------------------------------------------------------------------------- 1 | param($rootPath, $toolsPath, $package, $project) 2 | 3 | # Bail out if scaffolding is disabled (probably because you're running an incompatible version of T4Scaffolding.dll) 4 | if (-not (Get-Module T4Scaffolding)) { 5 | # Remove any existing MvcScaffolding providers (which will break the entire Add Controller dialog without the T4Scaffolding Module) 6 | $mvcScaffoldingProviderID = "{9EC893D9-B925-403C-B785-A50545149521}" 7 | # There can be multiple, one per loaded ASP.NET MVC tooling DLL, if your VS instance has multiple versions of ASP.NET MVC tooling loaded 8 | $scaffolderProviderTypes = [System.AppDomain]::CurrentDomain.GetAssemblies() | %{ $_.GetType("Microsoft.VisualStudio.Web.Mvc.Scaffolding.ScaffolderProviders") } | ?{ $_ } 9 | $scaffolderProviderTypes | %{ 10 | $allProviders = $_.GetProperty("Providers").GetValue($null, $null) 11 | 12 | $existingMvcScaffoldingProviders = $allProviders | ?{ $_.ID -eq $mvcScaffoldingProviderID } 13 | $existingMvcScaffoldingProviders | %{ $allProviders.Remove($_) } | Out-Null 14 | } 15 | return 16 | } 17 | 18 | # Enable tab expansion 19 | if (!$global:scaffolderTabExpansion) { $global:scaffolderTabExpansion = @{ } } 20 | $global:scaffolderTabExpansion["MvcScaffolding.RazorView"] = $global:scaffolderTabExpansion["MvcScaffolding.AspxView"] = { 21 | param($filter, $allTokens) 22 | $secondLastToken = $allTokens[-2] 23 | if ($secondLastToken -eq 'Template') { 24 | return @("Create", "Delete", "Details", "Edit", "Index") 25 | } 26 | } 27 | 28 | # Enable MVC 3 Tools Update "Add Controller" dialog integration 29 | . (Join-Path $toolsPath "registerWithMvcTooling.ps1") $rootPath $toolsPath 30 | 31 | function CountSolutionFilesByExtension($extension) { 32 | $files = (Get-Project).DTE.Solution ` 33 | | ?{ $_.FileName } ` 34 | | %{ [System.IO.Path]::GetDirectoryName($_.FileName) } ` 35 | | ?{$_}` 36 | | %{ [System.IO.Directory]::EnumerateFiles($_, "*." + $extension, [System.IO.SearchOption]::AllDirectories) } 37 | ($files | Measure-Object).Count 38 | } 39 | 40 | function InferPreferredViewEngine() { 41 | # Assume you want Razor except if you already have some ASPX views and no Razor ones 42 | if ((CountSolutionFilesByExtension aspx) -eq 0) { return "razor" } 43 | if (((CountSolutionFilesByExtension cshtml) -gt 0) -or ((CountSolutionFilesByExtension vbhtml) -gt 0)) { return "razor" } 44 | return "aspx" 45 | } 46 | 47 | # Ensure you've got some default settings for each of the included scaffolders 48 | Set-DefaultScaffolder -Name Controller -Scaffolder MvcScaffolding.Controller -SolutionWide -DoNotOverwriteExistingSetting 49 | Set-DefaultScaffolder -Name Views -Scaffolder MvcScaffolding.Views -SolutionWide -DoNotOverwriteExistingSetting 50 | Set-DefaultScaffolder -Name Action -Scaffolder MvcScaffolding.Action -SolutionWide -DoNotOverwriteExistingSetting 51 | Set-DefaultScaffolder -Name UnitTest -Scaffolder MvcScaffolding.ActionUnitTest -SolutionWide -DoNotOverwriteExistingSetting 52 | 53 | # Infer which view engine you're using based on the files in your project 54 | $viewScaffolder = if ([string](InferPreferredViewEngine) -eq 'aspx') { "MvcScaffolding.AspxView" } else { "MvcScaffolding.RazorView" } 55 | Set-DefaultScaffolder -Name View -Scaffolder $viewScaffolder -SolutionWide -DoNotOverwriteExistingSetting -------------------------------------------------------------------------------- /MvcScaffolding/install.ps1: -------------------------------------------------------------------------------- 1 | param($rootPath, $toolsPath, $package, $project) 2 | 3 | # Try to delete InstallationDummyFile.txt 4 | if ($project) { 5 | $project.ProjectItems | ?{ $_.Name -eq "InstallationDummyFile.txt" } | %{ $_.Delete() } 6 | } -------------------------------------------------------------------------------- /MvcScaffolding/scaffoldViaDialogTempScript.ps1: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ASP.NET-MVC-Scaffolding 2 | A GitHub repository of the Codeplex Mvc Scaffolding Project (https://mvcscaffolding.codeplex.com/) 3 | This project is a continuation of the work done by Steve Sanderson & Scott Hanselman on developing MvcScaffolding. 4 | 5 | The original source can be found at: https://mvcscaffolding.codeplex.com/ 6 | 7 | The original is no longer supported by the original authors as they've now introduced an alternative Asp.Net Scaffolding (http://www.asp.net/visual-studio/overview/2013/aspnet-scaffolding-overview) to Visual Studio. However, this leaves users of the MvcScaffolding project in the lurch if they wish to continue to use their own templates and scripts with Visual Studio 2013 and above. 8 | 9 | This project fixes the issues users were experiencing and has been tested with: 10 | * Visual Studio 2013 11 | * Visual Studio 2015 12 | * Visual Studio 2017 13 | 14 | The NuGet packages can be found in the following addresses: 15 | * [T4Scaffolding.Core.VS2015](https://www.nuget.org/packages/T4Scaffolding.Core.VS2015/) (VS2013/VS2015) 16 | * [T4Scaffolding.VS2015](https://www.nuget.org/packages/T4Scaffolding.VS2015/) (VS2013/VS2015) 17 | * [MvcScaffolding.VS2015](https://www.nuget.org/packages/MvcScaffolding.VS2015/) (VS2013/VS2015) 18 | 19 | * [T4Scaffolding.Core.VS2017](https://www.nuget.org/packages/T4Scaffolding.Core.VS2017/) 20 | * [T4Scaffolding.VS2017](https://www.nuget.org/packages/T4Scaffolding.VS2017/) 21 | * [MvcScaffolding.VS2017](https://www.nuget.org/packages/MvcScaffolding.VS2017/) 22 | 23 | Happy Scaffolding! 24 | -------------------------------------------------------------------------------- /ReferenceAssemblies/NuGet.Console.Types.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processedbeets/ASP.NET-MVC-Scaffolding/e0a017930e88119aecae98d53240570624f338d1/ReferenceAssemblies/NuGet.Console.Types.dll -------------------------------------------------------------------------------- /ReferenceAssemblies/NuGet.VisualStudio.Test.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processedbeets/ASP.NET-MVC-Scaffolding/e0a017930e88119aecae98d53240570624f338d1/ReferenceAssemblies/NuGet.VisualStudio.Test.dll -------------------------------------------------------------------------------- /T4Scaffolding.Core/Cmdlets/AddClassMemberCmdlet.cs: -------------------------------------------------------------------------------- 1 | using System.Management.Automation; 2 | using EnvDTE; 3 | using T4Scaffolding.Core.EnvDTE; 4 | 5 | namespace T4Scaffolding.Cmdlets 6 | { 7 | /// 8 | /// A simple wrapper around T4Scaffolding.Core.EnvDTE.EnvDTEExtensions.AddMemberFromSourceCode, since it's 9 | /// difficult to invoke extension methods from PowerShell (and even more difficult to pass the PowerShell 10 | /// COM object wrappers to them) 11 | /// 12 | [Cmdlet(VerbsCommon.Add, "ClassMember")] 13 | public class AddClassMemberCmdlet : ScaffoldingBaseCmdlet 14 | { 15 | [Parameter(Mandatory = true, Position = 1, ValueFromPipelineByPropertyName = true)] 16 | public PSObject CodeClass { get; set; } 17 | 18 | [Parameter(Mandatory = true, Position = 2, ValueFromPipelineByPropertyName = true)] 19 | public string SourceCode { get; set; } 20 | 21 | [Parameter] 22 | public object Position { get; set; } 23 | 24 | [Parameter] 25 | public int TextFormatOptions { get; set; } 26 | 27 | public AddClassMemberCmdlet() : base(null, null, null) 28 | { 29 | TextFormatOptions = (int)vsEPReplaceTextOptions.vsEPReplaceTextAutoformat; // Default if not specified 30 | } 31 | 32 | protected override void ProcessRecordCore() 33 | { 34 | var castCodeClass = CodeClass.BaseObject as CodeType; 35 | if (castCodeClass == null) 36 | WriteError("Unable to cast the supplied CodeClass value to the type EnvDTE.CodeType"); 37 | else 38 | castCodeClass.AddMemberFromSourceCode(SourceCode, Position, (vsEPReplaceTextOptions)TextFormatOptions); 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /T4Scaffolding.Core/Cmdlets/GetDefaultScaffolderCmdlet.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Management.Automation; 4 | using T4Scaffolding.Core.Configuration; 5 | using T4Scaffolding.NuGetServices.Services; 6 | 7 | namespace T4Scaffolding.Cmdlets 8 | { 9 | [Cmdlet(VerbsCommon.Get, "DefaultScaffolder")] 10 | public class GetDefaultScaffolderCmdlet : ScaffoldingBaseCmdlet 11 | { 12 | private readonly Lazy _configStore; 13 | 14 | [Parameter(Position = 0, ValueFromPipelineByPropertyName = true)] 15 | public string Name { get; set; } 16 | 17 | [Parameter] 18 | public string Project { get; set; } 19 | 20 | public GetDefaultScaffolderCmdlet() : this(null, null, null) 21 | { 22 | } 23 | 24 | internal GetDefaultScaffolderCmdlet(ISolutionManager solutionManager, IVsPackageManagerFactory packageManagerFactory, IScaffoldingConfigStore configStore) 25 | : base(solutionManager, packageManagerFactory, null) 26 | { 27 | _configStore = new Lazy(() => { 28 | return configStore ?? new XmlScaffoldingConfigStore(SolutionManager); 29 | }); 30 | } 31 | 32 | protected override void ProcessRecordCore() 33 | { 34 | var project = SolutionManager.GetProject(string.IsNullOrEmpty(Project) ? SolutionManager.DefaultProjectName : Project); 35 | if (project == null) { 36 | WriteError(string.Format("Could not find project '{0}'", Project ?? string.Empty)); 37 | return; 38 | } 39 | 40 | // First get solution entries 41 | var results = (from entry in _configStore.Value.GetSolutionDefaultScaffolders() 42 | where string.IsNullOrEmpty(Name) || entry.DefaultName.Equals(Name, StringComparison.OrdinalIgnoreCase) 43 | select entry).ToDictionary(x => x.DefaultName, StringComparer.OrdinalIgnoreCase); 44 | 45 | // Then overlay the project entries 46 | var projectEntries = (from entry in _configStore.Value.GetProjectDefaultScaffolders(project) 47 | where string.IsNullOrEmpty(Name) || entry.DefaultName.Equals(Name, StringComparison.OrdinalIgnoreCase) 48 | select entry).ToDictionary(x => x.DefaultName, StringComparer.OrdinalIgnoreCase); 49 | foreach (var projectEntry in projectEntries) { 50 | results[projectEntry.Key] = projectEntry.Value; 51 | } 52 | 53 | WriteObject(results.Select(x => x.Value), true); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /T4Scaffolding.Core/Cmdlets/GetPluralizedWordCmdlet.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Data.Entity.Design.PluralizationServices; 3 | using System.Globalization; 4 | using System.Management.Automation; 5 | using System.Threading; 6 | 7 | namespace T4Scaffolding.Cmdlets 8 | { 9 | [Cmdlet(VerbsCommon.Get, "PluralizedWord")] 10 | public class GetPluralizedWordCmdlet : ScaffoldingBaseCmdlet 11 | { 12 | [Parameter(Mandatory = true, Position = 1, ValueFromPipelineByPropertyName = true)] 13 | public string Word { get; set; } 14 | 15 | [Parameter] 16 | public string Culture { get; set; } 17 | 18 | public GetPluralizedWordCmdlet() : base(null, null, null) 19 | { 20 | Culture = Thread.CurrentThread.CurrentUICulture.Name; 21 | } 22 | 23 | protected override void ProcessRecordCore() 24 | { 25 | PluralizationService pluralizationService; 26 | 27 | try { 28 | pluralizationService = PluralizationService.CreateService(new CultureInfo(Culture)); 29 | } catch(NotImplementedException) { 30 | // Unsupported culture 31 | WriteDebug(string.Format("Cannot pluralize '{0}' because culture '{1}' is not yet supported by System.Data.Entity.Design.PluralizationServices. Leaving the word unpluralized.", Word, Culture)); 32 | WriteObject(Word); 33 | return; 34 | } 35 | 36 | WriteObject(pluralizationService.Pluralize(Word)); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /T4Scaffolding.Core/Cmdlets/GetPrimaryKeyCmdlet.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Management.Automation; 4 | using EnvDTE; 5 | using T4Scaffolding.Core.EnvDTE; 6 | using T4Scaffolding.Core.PrimaryKeyLocators; 7 | using T4Scaffolding.Core.ProjectTypeLocators; 8 | using T4Scaffolding.NuGetServices.Services; 9 | 10 | namespace T4Scaffolding.Cmdlets 11 | { 12 | [Cmdlet(VerbsCommon.Get, "PrimaryKey")] 13 | public class GetPrimaryKeyCmdlet : ScaffoldingBaseCmdlet 14 | { 15 | private readonly IProjectTypeLocator _projectTypeLocator; 16 | 17 | [Parameter(Position = 0, Mandatory = true, ValueFromPipelineByPropertyName = true)] 18 | public string Type { get; set; } 19 | 20 | [Parameter] 21 | public string Project { get; set; } 22 | 23 | [Parameter] 24 | public SwitchParameter ErrorIfNotFound { get; set; } 25 | 26 | public GetPrimaryKeyCmdlet() : this(null, new EnvDTETypeLocator()) { } 27 | internal GetPrimaryKeyCmdlet(ISolutionManager solutionManager, IProjectTypeLocator projectTypeLocator) 28 | : base(solutionManager, null, null) 29 | { 30 | _projectTypeLocator = projectTypeLocator; 31 | } 32 | 33 | protected override void ProcessRecordCore() 34 | { 35 | if (string.IsNullOrEmpty(Type)) throw new InvalidOperationException("Specify a value for 'Type'."); 36 | 37 | var project = SolutionManager.GetProject(string.IsNullOrEmpty(Project) ? SolutionManager.DefaultProjectName : Project); 38 | if (project == null) { 39 | WriteError(string.Format("Could not find project '{0}'", Project ?? string.Empty)); 40 | return; 41 | } 42 | 43 | var foundClass = _projectTypeLocator.FindUniqueType(project, Type); 44 | var primaryKeyProperties = PrimaryKeyLocation.GetPrimaryKeys(foundClass).ToList(); 45 | switch (primaryKeyProperties.Count) 46 | { 47 | case 0: 48 | if (ErrorIfNotFound) { 49 | WriteError(string.Format("Cannot find primary key property for type '{0}'. No properties appear to be primary keys.", foundClass.FullName)); 50 | } 51 | break; 52 | case 1: 53 | WriteObject(primaryKeyProperties.Single().Name); 54 | break; 55 | default: 56 | if (ErrorIfNotFound) { 57 | var primaryKeyPropertyNames = string.Join(", ", primaryKeyProperties.Select(x => x.Name)); 58 | WriteError(string.Format("Cannot find primary key property for type '{0}'. Multiple properties appear to be primary keys: {1}", foundClass.FullName, primaryKeyPropertyNames)); 59 | } 60 | break; 61 | } 62 | } 63 | } 64 | } -------------------------------------------------------------------------------- /T4Scaffolding.Core/Cmdlets/GetProjectAspNetMvcVersionCmdlet.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Management.Automation; 4 | using T4Scaffolding.Core; 5 | using T4Scaffolding.NuGetServices.Services; 6 | using T4Scaffolding.NuGetServices.ExtensionMethods; 7 | 8 | namespace T4Scaffolding.Cmdlets 9 | { 10 | [Cmdlet(VerbsCommon.Get, "ProjectAspNetMvcVersion")] 11 | public class GetProjectAspNetMvcVersionCmdlet : ScaffoldingBaseCmdlet 12 | { 13 | [Parameter] 14 | public string Project { get; set; } 15 | 16 | public GetProjectAspNetMvcVersionCmdlet() : this(null) { } 17 | internal GetProjectAspNetMvcVersionCmdlet(ISolutionManager solutionManager) : base(solutionManager, null, null) 18 | { 19 | } 20 | 21 | protected override void ProcessRecordCore() 22 | { 23 | var project = SolutionManager.GetProject(string.IsNullOrEmpty(Project) ? SolutionManager.DefaultProjectName : Project); 24 | if (project == null) { 25 | WriteError(string.Format("Could not find project '{0}'", Project ?? string.Empty)); 26 | return; 27 | } 28 | 29 | var projectTypeGuids = project.GetProjectTypeGuids(); 30 | if (projectTypeGuids.Contains(VsConstants.Mvc3ProjectTypeGuid, StringComparer.OrdinalIgnoreCase)) { 31 | WriteObject(3); 32 | } else if (projectTypeGuids.Contains(VsConstants.Mvc2ProjectTypeGuid, StringComparer.OrdinalIgnoreCase)) { 33 | WriteObject(2); 34 | } else if (projectTypeGuids.Contains(VsConstants.Mvc1ProjectTypeGuid, StringComparer.OrdinalIgnoreCase)) { 35 | WriteObject(1); 36 | } 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /T4Scaffolding.Core/Cmdlets/GetProjectFolderCmdlet.cs: -------------------------------------------------------------------------------- 1 | using System.Management.Automation; 2 | using T4Scaffolding.Core; 3 | using T4Scaffolding.Core.FileSystem; 4 | using T4Scaffolding.NuGetServices.Services; 5 | 6 | namespace T4Scaffolding.Cmdlets 7 | { 8 | [Cmdlet(VerbsCommon.Get, "ProjectFolder")] 9 | public class GetProjectFolderCmdlet : ScaffoldingBaseCmdlet 10 | { 11 | private readonly IFileSystem _fileSystem; 12 | 13 | [Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true)] 14 | public string Path { get; set; } 15 | 16 | [Parameter] 17 | public string Project { get; set; } 18 | 19 | [Parameter] 20 | public SwitchParameter Create { get; set; } 21 | 22 | 23 | public GetProjectFolderCmdlet() 24 | : this(null, new DefaultFileSystem()) { } 25 | 26 | internal GetProjectFolderCmdlet(ISolutionManager solutionManager, IFileSystem fileSystem) 27 | : base(solutionManager, null, null) 28 | { 29 | _fileSystem = fileSystem; 30 | } 31 | 32 | protected override void ProcessRecordCore() 33 | { 34 | var project = SolutionManager.GetProject(string.IsNullOrEmpty(Project) ? SolutionManager.DefaultProjectName : Project); 35 | if (project == null) { 36 | WriteError(string.Format("Could not find project '{0}'", Project ?? string.Empty)); 37 | return; 38 | } 39 | var result = project.GetOrCreateProjectItems(Path, Create.ToBool(), _fileSystem); 40 | if (result != null) 41 | WriteObject(result); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /T4Scaffolding.Core/Cmdlets/GetProjectItemCmdlet.cs: -------------------------------------------------------------------------------- 1 | using System.Management.Automation; 2 | using T4Scaffolding.NuGetServices.Services; 3 | using T4Scaffolding.NuGetServices.ExtensionMethods; 4 | 5 | namespace T4Scaffolding.Cmdlets 6 | { 7 | [Cmdlet(VerbsCommon.Get, "ProjectItem")] 8 | public class GetProjectItemCmdlet : ScaffoldingBaseCmdlet 9 | { 10 | public GetProjectItemCmdlet() : this(null) { } 11 | internal GetProjectItemCmdlet(ISolutionManager solutionManager) : base(solutionManager, null, null) 12 | { 13 | } 14 | 15 | [Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true)] 16 | public string Path { get; set; } 17 | 18 | [Parameter] 19 | public string Project { get; set; } 20 | 21 | protected override void ProcessRecordCore() 22 | { 23 | var project = SolutionManager.GetProject(string.IsNullOrEmpty(Project) ? SolutionManager.DefaultProjectName : Project); 24 | if (project == null) { 25 | WriteError(string.Format("Could not find project '{0}'", Project ?? string.Empty)); 26 | return; 27 | } 28 | 29 | var result = project.GetProjectItem(Path); 30 | if (result != null) 31 | WriteObject(result); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /T4Scaffolding.Core/Cmdlets/GetProjectLanguageCmdlet.cs: -------------------------------------------------------------------------------- 1 | using System.Management.Automation; 2 | using T4Scaffolding.Core; 3 | using T4Scaffolding.NuGetServices.Services; 4 | 5 | namespace T4Scaffolding.Cmdlets 6 | { 7 | [Cmdlet(VerbsCommon.Get, "ProjectLanguage")] 8 | public class GetProjectLanguageCmdlet : ScaffoldingBaseCmdlet 9 | { 10 | [Parameter] 11 | public string Project { get; set; } 12 | 13 | public GetProjectLanguageCmdlet() : this(null) { } 14 | internal GetProjectLanguageCmdlet(ISolutionManager solutionManager) : base(solutionManager, null, null) 15 | { 16 | } 17 | 18 | protected override void ProcessRecordCore() 19 | { 20 | var project = SolutionManager.GetProject(string.IsNullOrEmpty(Project) ? SolutionManager.DefaultProjectName : Project); 21 | if (project == null) { 22 | WriteError(string.Format("Could not find project '{0}'", Project ?? string.Empty)); 23 | return; 24 | } 25 | 26 | var result = project.GetCodeLanguage(); 27 | if (result != null) 28 | WriteObject(result); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /T4Scaffolding.Core/Cmdlets/GetProjectTypeCmdlet.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Management.Automation; 4 | using EnvDTE; 5 | using T4Scaffolding.Core.ProjectTypeLocators; 6 | using T4Scaffolding.NuGetServices.Services; 7 | using T4Scaffolding.NuGetServices.Threading; 8 | 9 | namespace T4Scaffolding.Cmdlets 10 | { 11 | [Cmdlet(VerbsCommon.Get, "ProjectType")] 12 | public class GetProjectTypeCmdlet : ScaffoldingBaseCmdlet 13 | { 14 | private readonly IProjectTypeLocator _projectTypeLocator; 15 | 16 | [Parameter(Position = 0, Mandatory = true, ValueFromPipelineByPropertyName = true)] 17 | public string Type { get; set; } 18 | 19 | [Parameter] 20 | public string Project { get; set; } 21 | 22 | [Parameter] 23 | public SwitchParameter BlockUi { get; set; } 24 | 25 | [Parameter] 26 | public SwitchParameter AllowMultiple { get; set; } 27 | 28 | public GetProjectTypeCmdlet() : this(null, new EnvDTETypeLocator()) { } 29 | internal GetProjectTypeCmdlet(ISolutionManager solutionManager, IProjectTypeLocator projectTypeLocator) 30 | : base(solutionManager, null, null) 31 | { 32 | _projectTypeLocator = projectTypeLocator; 33 | } 34 | 35 | protected override void ProcessRecordCore() 36 | { 37 | var project = SolutionManager.GetProject(string.IsNullOrEmpty(Project) ? SolutionManager.DefaultProjectName : Project); 38 | if (project == null) { 39 | WriteError(string.Format("Could not find project '{0}'", Project ?? string.Empty)); 40 | return; 41 | } 42 | 43 | Func> codeTypeFunc = AllowMultiple.IsPresent 44 | ? () => _projectTypeLocator.FindTypes(project, Type) 45 | : (Func>)(() => new[] { _projectTypeLocator.FindUniqueType(project, Type) }); 46 | var codeType = codeTypeFunc(); 47 | if (codeType != null) 48 | WriteObject(codeType, true); 49 | } 50 | } 51 | } -------------------------------------------------------------------------------- /T4Scaffolding.Core/Cmdlets/GetRelatedEntitiesCmdlet.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Management.Automation; 3 | using T4Scaffolding.Core.ProjectTypeLocators; 4 | using T4Scaffolding.Core.RelatedEntityLocators; 5 | using T4Scaffolding.NuGetServices.Services; 6 | 7 | namespace T4Scaffolding.Cmdlets 8 | { 9 | [Cmdlet(VerbsCommon.Get, "RelatedEntities")] 10 | public class GetRelatedEntitiesCmdlet : ScaffoldingBaseCmdlet 11 | { 12 | private readonly IProjectTypeLocator _projectTypeLocator; 13 | 14 | [Parameter(Position = 0, Mandatory = true, ValueFromPipelineByPropertyName = true)] 15 | public string Type { get; set; } 16 | 17 | [Parameter] 18 | public string Project { get; set; } 19 | 20 | public GetRelatedEntitiesCmdlet() : this(null, new EnvDTETypeLocator()) { } 21 | internal GetRelatedEntitiesCmdlet(ISolutionManager solutionManager, IProjectTypeLocator projectTypeLocator) 22 | : base(solutionManager, null, null) 23 | { 24 | _projectTypeLocator = projectTypeLocator; 25 | } 26 | 27 | protected override void ProcessRecordCore() 28 | { 29 | if (string.IsNullOrEmpty(Type)) throw new InvalidOperationException("Specify a value for 'Type'."); 30 | 31 | var project = SolutionManager.GetProject(string.IsNullOrEmpty(Project) ? SolutionManager.DefaultProjectName : Project); 32 | if (project == null) { 33 | WriteError(string.Format("Could not find project '{0}'", Project ?? string.Empty)); 34 | return; 35 | } 36 | 37 | var foundType = _projectTypeLocator.FindUniqueType(project, Type); 38 | var relatedEntityInfos = RelatedEntityLocation.CurrentRelatedEntityLocator.GetRelatedEntities(foundType, project, _projectTypeLocator); 39 | WriteObject(relatedEntityInfos, true); 40 | } 41 | } 42 | } -------------------------------------------------------------------------------- /T4Scaffolding.Core/Cmdlets/GetScaffolderCmdlet.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Management.Automation; 4 | using T4Scaffolding.Core.Configuration; 5 | using T4Scaffolding.Core.FileSystem; 6 | using T4Scaffolding.Core.ScaffolderLocators; 7 | using T4Scaffolding.NuGetServices.Services; 8 | 9 | namespace T4Scaffolding.Cmdlets 10 | { 11 | [Cmdlet(VerbsCommon.Get, "Scaffolder")] 12 | public class GetScaffolderCmdlet : ScaffoldingBaseCmdlet 13 | { 14 | private readonly Lazy _scaffolderLocator; 15 | 16 | [Parameter(Position = 0, ValueFromPipelineByPropertyName = true)] 17 | public string Name { get; set; } 18 | 19 | [Parameter] 20 | public string Project { get; set; } 21 | 22 | [Parameter] 23 | public SwitchParameter IncludeHidden { get; set; } 24 | 25 | public GetScaffolderCmdlet() 26 | : this(null, null, null) 27 | { 28 | } 29 | 30 | internal GetScaffolderCmdlet(ISolutionManager solutionManager, IVsPackageManagerFactory vsPackageManagerFactory, IScaffolderLocator scaffolderLocator) 31 | : base(solutionManager, vsPackageManagerFactory, null) 32 | { 33 | // Can't read the value of CommandInvoker until *after* the constructor finishes, hence lazy 34 | _scaffolderLocator = new Lazy( 35 | () => scaffolderLocator ?? new Ps1ScaffolderLocator(CommandInvoker, PackageManager, null, new DefaultFileSystem(), new XmlScaffoldingConfigStore(SolutionManager)) 36 | ); 37 | } 38 | 39 | protected override void ProcessRecordCore() 40 | { 41 | var project = SolutionManager.GetProject(string.IsNullOrEmpty(Project) ? SolutionManager.DefaultProjectName : Project); 42 | if (project == null) { 43 | WriteError(string.Format("Could not find project '{0}'", Project ?? string.Empty)); 44 | return; 45 | } 46 | 47 | var scaffolders = from scaffolder in _scaffolderLocator.Value.GetScaffolders(project, Name, resolveDefaultNames: true) 48 | where (scaffolder.ScaffolderAttribute == null) 49 | || (!scaffolder.ScaffolderAttribute.HideInConsole) 50 | || IncludeHidden.IsPresent 51 | select scaffolder; 52 | WriteObject(scaffolders, enumerateCollection: true); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /T4Scaffolding.Core/Cmdlets/GetSingularizedWordCmdlet.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Data.Entity.Design.PluralizationServices; 3 | using System.Globalization; 4 | using System.Management.Automation; 5 | using System.Threading; 6 | 7 | namespace T4Scaffolding.Cmdlets 8 | { 9 | [Cmdlet(VerbsCommon.Get, "SingularizedWord")] 10 | public class GetSingularizedWordCmdlet : ScaffoldingBaseCmdlet 11 | { 12 | [Parameter(Mandatory = true, Position = 1, ValueFromPipelineByPropertyName = true)] 13 | public string Word { get; set; } 14 | 15 | [Parameter] 16 | public string Culture { get; set; } 17 | 18 | public GetSingularizedWordCmdlet() : base(null, null, null) 19 | { 20 | Culture = Thread.CurrentThread.CurrentUICulture.Name; 21 | } 22 | 23 | protected override void ProcessRecordCore() 24 | { 25 | PluralizationService pluralizationService; 26 | 27 | try { 28 | pluralizationService = PluralizationService.CreateService(new CultureInfo(Culture)); 29 | } catch(NotImplementedException) { 30 | // Unsupported culture 31 | WriteDebug(string.Format("Cannot singularized '{0}' because culture '{1}' is not yet supported by System.Data.Entity.Design.PluralizationServices. Leaving the word unsingularized.", Word, Culture)); 32 | WriteObject(Word); 33 | return; 34 | } 35 | 36 | WriteObject(pluralizationService.Singularize(Word)); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /T4Scaffolding.Core/Cmdlets/GlobalCommandRunner.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Management.Automation; 3 | using System.Management.Automation.Runspaces; 4 | using System.Threading; 5 | 6 | namespace T4Scaffolding.Cmdlets 7 | { 8 | /// 9 | /// This is a temporary hack, erm, *workaround* until NuGet lets packages export PowerShell module members to the 10 | /// Package Manager Console. Once that is resolved, this class will be removed. Don't call it from other packages! 11 | /// Marking as obsolete as a further warning. 12 | /// 13 | [Obsolete] 14 | public static class GlobalCommandRunner 15 | { 16 | private static readonly object _inCallbackLock = new object(); 17 | public static void Run(string script, bool allowMultipleRuns) 18 | { 19 | var runspace = Runspace.DefaultRunspace; 20 | // When the user is interacting with the console (e.g., first installing the package), the runspace 21 | // is busy, so we need to wait until it becomes free 22 | EventHandler callback = null; 23 | callback = (sender, e) => 24 | { 25 | lock (_inCallbackLock) 26 | { 27 | if ((runspace != null) && (runspace.RunspaceAvailability == RunspaceAvailability.Available)) 28 | { 29 | runspace.AvailabilityChanged -= callback; 30 | RunScriptNow(runspace, script); 31 | runspace = null; // Basic way of coordinating activity among the two types of callback 32 | } 33 | } 34 | }; 35 | runspace.AvailabilityChanged += callback; 36 | 37 | // When the user first opens Visual Studio, the runspace claims to be available but in fact is not, 38 | // so we wait a little (arbitrary) while and then try to run the script. In case this fails (perhaps we 39 | // didn't wait long enough), if allowMultipleRuns=true, we'll try again later when the runspace informs us it's free. 40 | ThreadPool.QueueUserWorkItem(e => 41 | { 42 | System.Threading.Thread.Sleep(1000); 43 | lock (_inCallbackLock) 44 | { 45 | if ((runspace != null) && (runspace.RunspaceAvailability == RunspaceAvailability.Available)) 46 | { 47 | RunScriptNow(runspace, script); 48 | if (!allowMultipleRuns) 49 | { 50 | runspace = null; 51 | } 52 | } 53 | } 54 | }); 55 | } 56 | 57 | private static void RunScriptNow(Runspace runspace, string script) 58 | { 59 | using (var ps = PowerShell.Create()) 60 | { 61 | ps.Runspace = runspace; 62 | ps.Commands = new PSCommand(); 63 | ps.Commands.AddScript(script, false); 64 | ps.Invoke(); 65 | } 66 | } 67 | } 68 | } -------------------------------------------------------------------------------- /T4Scaffolding.Core/Cmdlets/ScaffoldingBaseCmdlet.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Management.Automation; 6 | using System.Management.Automation.Runspaces; 7 | using T4Scaffolding.Core.CommandInvokers; 8 | using T4Scaffolding.NuGetServices; 9 | using T4Scaffolding.NuGetServices.Services; 10 | 11 | namespace T4Scaffolding.Cmdlets 12 | { 13 | public abstract class ScaffoldingBaseCmdlet : ScaffoldingNuGetBaseCmdlet 14 | { 15 | private readonly Lazy _commandInvoker; 16 | 17 | protected IPowershellCommandInvoker CommandInvoker { get { return _commandInvoker.Value; } } 18 | 19 | protected ScaffoldingBaseCmdlet() 20 | : this(null, null, null) 21 | { 22 | } 23 | 24 | internal ScaffoldingBaseCmdlet(ISolutionManager solutionManager, IVsPackageManagerFactory vsPackageManagerFactory, IPowershellCommandInvoker commandInvoker) 25 | : base(solutionManager, vsPackageManagerFactory) 26 | { 27 | // Command intrinsics can't be accessed until the PSCmdlet enters the "ProcessRecord" phase, 28 | // so we have to defer evaluation of the following things until then. To support unit testing, 29 | // it's possible to override their instantiation by passing a non-null instance to the constructor. 30 | 31 | _commandInvoker = new Lazy(() => { 32 | return commandInvoker ?? new DefaultPowershellCommandInvoker(InvokeCommand, MyInvocation); 33 | }); 34 | } 35 | 36 | internal void Execute() 37 | { 38 | BeginProcessing(); 39 | ProcessRecord(); 40 | EndProcessing(); 41 | } 42 | 43 | protected IEnumerable InvokeCmdletCaptureOutput(string cmdletName, Hashtable args) 44 | { 45 | var cmdlet = CommandInvoker.GetCommand(cmdletName, CommandTypes.Cmdlet); 46 | return CommandInvoker.InvokeCaptureOutput(cmdlet, args).Select(x => x.BaseObject).OfType(); 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /T4Scaffolding.Core/Cmdlets/SetIsCheckedOutCmdlet.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Management.Automation; 3 | using T4Scaffolding.Core; 4 | using T4Scaffolding.NuGetServices.Services; 5 | using T4Scaffolding.NuGetServices.ExtensionMethods; 6 | 7 | namespace T4Scaffolding.Cmdlets 8 | { 9 | [Cmdlet(VerbsCommon.Set, "IsCheckedOut")] 10 | public class SetIsCheckedOutCmdlet : ScaffoldingBaseCmdlet 11 | { 12 | [Parameter(Mandatory = true, Position = 0, ValueFromPipelineByPropertyName = true)] 13 | public string Path { get; set; } 14 | 15 | [Parameter] 16 | public string Project { get; set; } 17 | 18 | public SetIsCheckedOutCmdlet() : this(null) 19 | { 20 | } 21 | 22 | public SetIsCheckedOutCmdlet(ISolutionManager solutionManager) : base(solutionManager, null, null) 23 | { 24 | } 25 | 26 | protected override void ProcessRecordCore() 27 | { 28 | if (string.IsNullOrEmpty(Path)) 29 | throw new InvalidOperationException("Specify a value for 'Path'"); 30 | 31 | // Resolve project-relative paths, as long as we know what project to look inside 32 | if (!System.IO.Path.IsPathRooted(Path)) { 33 | var project = SolutionManager.GetProject(string.IsNullOrEmpty(Project) ? SolutionManager.DefaultProjectName : Project); 34 | if (project == null) { 35 | WriteError(string.Format("Could not find project '{0}'", Project ?? string.Empty)); 36 | return; 37 | } 38 | 39 | var projectDir = System.IO.Path.GetDirectoryName(project.GetFullPath()); 40 | Path = System.IO.Path.Combine(projectDir, Path); 41 | } 42 | 43 | SolutionManager.EnsureCheckedOutIfExists(Path); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /T4Scaffolding.Core/ControllerScaffolderAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace T4Scaffolding 4 | { 5 | public class ControllerScaffolderAttribute : ScaffolderAttribute 6 | { 7 | public string DisplayName { get; set; } 8 | public bool SupportsModelType { get; set; } 9 | public bool SupportsDataContextType { get; set; } 10 | public bool SupportsViewScaffolder { get; set; } 11 | public Type ViewScaffolderSelector { get; set; } 12 | 13 | public ControllerScaffolderAttribute(string displayName) 14 | { 15 | if (string.IsNullOrEmpty(displayName)) 16 | throw new ArgumentException("Value cannot be null or empty", "displayName"); 17 | 18 | DisplayName = displayName; 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /T4Scaffolding.Core/Core/CommandInvokers/DefaultPowershellCommandInvoker.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Management.Automation; 6 | using System.Management.Automation.Runspaces; 7 | 8 | namespace T4Scaffolding.Core.CommandInvokers 9 | { 10 | internal class DefaultPowershellCommandInvoker : IPowershellCommandInvoker 11 | { 12 | private readonly CommandInvocationIntrinsics _invokeCommand; 13 | private readonly InvocationInfo _myInvocation; 14 | 15 | public DefaultPowershellCommandInvoker(CommandInvocationIntrinsics invokeCommand, InvocationInfo myInvocation) 16 | { 17 | _invokeCommand = invokeCommand; 18 | _myInvocation = myInvocation; 19 | } 20 | 21 | public IEnumerable InvokeCaptureOutput(CommandInfo commandInfo, Hashtable args) 22 | { 23 | if (commandInfo == null) throw new ArgumentNullException("commandInfo"); 24 | return _invokeCommand.InvokeScript("param($c, $a) return . $c @a", true, PipelineResultTypes.None, null, commandInfo, args); 25 | } 26 | 27 | public void InvokePipeToOutput(CommandInfo commandInfo, Hashtable args, PipelineResultTypes pipelineResultTypes) 28 | { 29 | if (commandInfo == null) throw new ArgumentNullException("commandInfo"); 30 | _invokeCommand.InvokeScript("param($c, $a) . $c @a", true, pipelineResultTypes, null, commandInfo, args); 31 | } 32 | 33 | public CommandInfo GetCommand(string command, CommandTypes commandTypes) 34 | { 35 | // Annoying special-case hack needed until NuGet can call init.ps1 in the same scope as the console. 36 | // This gets called implicitly while resolving dynamic params, and that call happens in a scope where 37 | // there is more than one copy of the T4Scaffolding module loaded. This leads to an ambiguous match error. 38 | // We can avoid this by finding that specific command using another Get-Command call. 39 | // Without this hack, you don't get tab-completion on scaffolder parameter names after a VS restart. 40 | if (string.Equals(command, "Invoke-Scaffolder", StringComparison.OrdinalIgnoreCase)) { 41 | var commandInfoPsObject = _invokeCommand.InvokeScript("Get-Command T4Scaffolding\\Invoke-Scaffolder"); 42 | return (CommandInfo)commandInfoPsObject.First().BaseObject; 43 | } 44 | 45 | return _invokeCommand.GetCommand(command, commandTypes); 46 | } 47 | 48 | public IDictionary BoundParameters 49 | { 50 | get { return _myInvocation.BoundParameters; } 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /T4Scaffolding.Core/Core/CommandInvokers/IPowershellCommandInvoker.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using System.Management.Automation; 4 | using System.Management.Automation.Runspaces; 5 | 6 | namespace T4Scaffolding.Core.CommandInvokers 7 | { 8 | public interface IPowershellCommandInvoker 9 | { 10 | CommandInfo GetCommand(string command, CommandTypes commandTypes); 11 | IEnumerable InvokeCaptureOutput(CommandInfo commandInfo, Hashtable args); 12 | void InvokePipeToOutput(CommandInfo commandInfo, Hashtable args, PipelineResultTypes pipelineResultTypes); 13 | IDictionary BoundParameters { get; } 14 | } 15 | } -------------------------------------------------------------------------------- /T4Scaffolding.Core/Core/Configuration/DefaultScaffolderConfigEntry.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Xml.Serialization; 3 | 4 | namespace T4Scaffolding.Core.Configuration 5 | { 6 | public class DefaultScaffolderConfigEntry 7 | { 8 | private string _defaultName; 9 | [XmlAttribute] public string DefaultName 10 | { 11 | get { return _defaultName; } 12 | set 13 | { 14 | if (string.IsNullOrEmpty(value)) 15 | throw new ArgumentException("ScaffolderName cannot be null or empty"); 16 | 17 | _defaultName = value; 18 | } 19 | } 20 | 21 | private string _scaffolderName; 22 | [XmlAttribute] public string ScaffolderName 23 | { 24 | get { return _scaffolderName; } 25 | set 26 | { 27 | if (string.IsNullOrEmpty(value)) 28 | throw new ArgumentException("ScaffolderName cannot be null or empty"); 29 | 30 | _scaffolderName = value; 31 | } 32 | } 33 | 34 | public DefaultScaffolderConfigEntry() 35 | { 36 | } 37 | 38 | public DefaultScaffolderConfigEntry(string defaultName, string scaffolderName) 39 | { 40 | DefaultName = defaultName; 41 | ScaffolderName = scaffolderName; 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /T4Scaffolding.Core/Core/Configuration/IScaffoldingConfigStore.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using EnvDTE; 3 | 4 | namespace T4Scaffolding.Core.Configuration 5 | { 6 | public interface IScaffoldingConfigStore 7 | { 8 | IQueryable GetProjectDefaultScaffolders(Project project); 9 | IQueryable GetSolutionDefaultScaffolders(); 10 | 11 | void SetProjectDefaultScaffolder(Project project, string defaultName, string scaffolderName, bool doNotOverwriteExistingSetting); 12 | void SetSolutionDefaultScaffolder(string defaultName, string scaffolderName, bool doNotOverwriteExistingSetting); 13 | } 14 | } -------------------------------------------------------------------------------- /T4Scaffolding.Core/Core/Configuration/XmlScaffoldingConfig.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Xml.Serialization; 3 | 4 | namespace T4Scaffolding.Core.Configuration 5 | { 6 | [XmlRoot("Config")] 7 | public class XmlScaffoldingConfig 8 | { 9 | [XmlArrayItem("Default")] 10 | public List DefaultScaffolders { get; set; } 11 | 12 | public XmlScaffoldingConfig() 13 | { 14 | DefaultScaffolders = new List(); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /T4Scaffolding.Core/Core/FileSystem/DefaultFileSystem.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.IO; 3 | 4 | namespace T4Scaffolding.Core.FileSystem 5 | { 6 | public class DefaultFileSystem : IFileSystem 7 | { 8 | public bool DirectoryExists(string path) 9 | { 10 | return Directory.Exists(path); 11 | } 12 | 13 | public bool FileExists(string path) 14 | { 15 | return File.Exists(path); 16 | } 17 | 18 | public void CreateDirectory(string path) 19 | { 20 | Directory.CreateDirectory(path); 21 | } 22 | 23 | public string ReadAllText(string path) 24 | { 25 | return File.ReadAllText(path); 26 | } 27 | 28 | public void WriteAllText(string path, string textContents) 29 | { 30 | File.WriteAllText(path, textContents); 31 | } 32 | 33 | public IEnumerable FindFiles(string path, string pattern, bool includeSubdirectories) 34 | { 35 | return Directory.EnumerateFiles(path, pattern, includeSubdirectories ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly); 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /T4Scaffolding.Core/Core/FileSystem/IFileSystem.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace T4Scaffolding.Core.FileSystem 4 | { 5 | public interface IFileSystem 6 | { 7 | bool DirectoryExists(string path); 8 | bool FileExists(string path); 9 | void CreateDirectory(string path); 10 | string ReadAllText(string path); 11 | void WriteAllText(string path, string textContents); 12 | IEnumerable FindFiles(string path, string pattern, bool includeSubdirectories); 13 | } 14 | } -------------------------------------------------------------------------------- /T4Scaffolding.Core/Core/PrimaryKeyLocators/IPrimaryKeyLocator.cs: -------------------------------------------------------------------------------- 1 | using EnvDTE; 2 | 3 | namespace T4Scaffolding.Core.PrimaryKeyLocators 4 | { 5 | public interface IPrimaryKeyLocator 6 | { 7 | bool IsPrimaryKey(CodeClass codeClass, CodeProperty codeProperty); 8 | } 9 | } -------------------------------------------------------------------------------- /T4Scaffolding.Core/Core/ProjectTypeLocators/IProjectTypeLocator.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using EnvDTE; 3 | 4 | namespace T4Scaffolding.Core.ProjectTypeLocators 5 | { 6 | public interface IProjectTypeLocator 7 | { 8 | IEnumerable FindTypes(Project project, string typeName); 9 | CodeType FindUniqueType(Project project, string typeName); 10 | IEnumerable FindAllTypes(Project project); 11 | } 12 | } -------------------------------------------------------------------------------- /T4Scaffolding.Core/Core/RelatedEntityLocators/IRelatedEntityLocator.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using EnvDTE; 3 | using T4Scaffolding.Core.ProjectTypeLocators; 4 | 5 | namespace T4Scaffolding.Core.RelatedEntityLocators 6 | { 7 | public interface IRelatedEntityLocator 8 | { 9 | IEnumerable GetRelatedEntities(CodeType codeType, Project project, IProjectTypeLocator projectTypeLocator); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /T4Scaffolding.Core/Core/RelatedEntityLocators/RelatedEntityInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Data.Entity.Design.PluralizationServices; 3 | using EnvDTE; 4 | 5 | namespace T4Scaffolding.Core.RelatedEntityLocators 6 | { 7 | [Serializable] 8 | public class RelatedEntityInfo 9 | { 10 | public RelationType RelationType { get; set; } 11 | public string RelationName { get; private set; } 12 | public string RelationNamePlural { get; private set; } 13 | public CodeProperty RelationProperty { get; private set; } // For parent entities, this is the primary key property. For child entities, it's the collection property. 14 | public CodeProperty LazyLoadingProperty { get; private set; } // For parent entities, this is optionally another property matching the relation name. For child entities, it's the collection property. 15 | public CodeType RelatedEntityType { get; private set; } 16 | public string RelatedEntityTypeNamePlural { get; private set; } 17 | public string RelatedEntityPrimaryKeyName { get; private set; } 18 | 19 | public RelatedEntityInfo(RelationType relationType, string relationName, CodeProperty relationProperty, CodeType relatedEntityType, string relatedEntityPrimaryKeyName, CodeProperty lazyLoadingProperty) 20 | { 21 | if (string.IsNullOrEmpty(relationName)) throw new ArgumentException("'relationName' cannot be null or empty."); 22 | if (relationProperty == null) throw new ArgumentNullException("relationProperty"); 23 | if (relatedEntityType == null) throw new ArgumentNullException("relatedEntityType"); 24 | if ((relationType == RelationType.Parent) && string.IsNullOrEmpty(relatedEntityPrimaryKeyName)) throw new ArgumentException("'relatedEntityPrimaryKeyName' cannot be null or empty for parent entities."); 25 | 26 | RelationType = relationType; 27 | RelationName = relationName; 28 | RelationNamePlural = Pluralize(relationName); 29 | RelationProperty = relationProperty; 30 | RelatedEntityType = relatedEntityType; 31 | RelatedEntityTypeNamePlural = Pluralize(relatedEntityType.Name); 32 | RelatedEntityPrimaryKeyName = relatedEntityPrimaryKeyName; 33 | LazyLoadingProperty = lazyLoadingProperty; 34 | } 35 | 36 | private static string Pluralize(string word) 37 | { 38 | try { 39 | var pluralizationService = PluralizationService.CreateService(System.Threading.Thread.CurrentThread.CurrentUICulture); 40 | return pluralizationService.Pluralize(word); 41 | } catch (NotImplementedException) { 42 | // Unsupported culture 43 | return word; 44 | } 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /T4Scaffolding.Core/Core/RelatedEntityLocators/RelationType.cs: -------------------------------------------------------------------------------- 1 | namespace T4Scaffolding.Core.RelatedEntityLocators 2 | { 3 | public enum RelationType 4 | { 5 | Parent = 1, 6 | Child = 2 7 | } 8 | } -------------------------------------------------------------------------------- /T4Scaffolding.Core/Core/ScaffolderLocators/IScaffolderLocator.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using EnvDTE; 3 | 4 | namespace T4Scaffolding.Core.ScaffolderLocators 5 | { 6 | public interface IScaffolderLocator 7 | { 8 | IEnumerable GetScaffolders(Project project, string name, bool resolveDefaultNames); 9 | } 10 | } -------------------------------------------------------------------------------- /T4Scaffolding.Core/Core/ScaffolderLocators/ScaffolderInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Management.Automation; 2 | 3 | namespace T4Scaffolding.Core.ScaffolderLocators 4 | { 5 | public class ScaffolderInfo 6 | { 7 | public string Name { get; private set; } 8 | public string PackageName { get; private set; } 9 | public string Location { get; private set; } 10 | public CommandInfo Command { get; private set; } 11 | public ScaffolderAttribute ScaffolderAttribute { get; set; } 12 | public string Description { get { return ScaffolderAttribute == null ? null : ScaffolderAttribute.Description; } } 13 | 14 | public ScaffolderInfo(string name, string packageName, string location, CommandInfo command, ScaffolderAttribute scaffolderAttribute) 15 | { 16 | Name = name; 17 | PackageName = packageName; 18 | Location = location; 19 | Command = command; 20 | ScaffolderAttribute = scaffolderAttribute; 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /T4Scaffolding.Core/Core/ScaffoldingConstants.cs: -------------------------------------------------------------------------------- 1 | namespace T4Scaffolding.Core 2 | { 3 | public static class ScaffoldingConstants 4 | { 5 | public const string CustomScaffoldersFolderPath = "CodeTemplates\\Scaffolders"; 6 | } 7 | } -------------------------------------------------------------------------------- /T4Scaffolding.Core/Core/Templating/ModelPropertyClassFeatures.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace T4Scaffolding.Core.Templating 4 | { 5 | static class ModelPropertyClassFeatures 6 | { 7 | public static IDictionary ModelPropertySourceForLanguage = new Dictionary { 8 | { 9 | "cs", 10 | @"<#+ 11 | dynamic Model { 12 | get { 13 | dynamic @this = this; 14 | return @this.Host.Model; 15 | } 16 | } 17 | #>" 18 | }, 19 | 20 | { 21 | "vb", 22 | @"<#+ 23 | Public ReadOnly Property Model As Object 24 | Get 25 | Dim thisDynamic As Object = Me 26 | Return thisDynamic.Host.Model 27 | End Get 28 | End Property 29 | #>" 30 | } 31 | }; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /T4Scaffolding.Core/Core/VsConstants.cs: -------------------------------------------------------------------------------- 1 | namespace T4Scaffolding.Core 2 | { 3 | internal static class VsConstants 4 | { 5 | internal const string Mvc1ProjectTypeGuid = "{603C0E0B-DB56-11DC-BE95-000D561079B0}"; 6 | internal const string Mvc2ProjectTypeGuid = "{F85E285D-A4E0-4152-9332-AB1D724D3325}"; 7 | internal const string Mvc3ProjectTypeGuid = "{E53F8FEA-EAE0-44A6-8774-FFD645390401}"; 8 | 9 | internal const string CsharpProjectTypeGuid = "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"; 10 | internal const string VbProjectTypeGuid = "{F184B08F-C81C-45F6-A57F-5ABD9991F28F}"; 11 | 12 | internal const string CsharpCodeModelLanguageGuid = "{B5E9BD34-6D3E-4B5D-925E-8A43B79820B4}"; 13 | internal const string VbCodeModelLanguageGuid = "{B5E9BD33-6D3E-4B5D-925E-8A43B79820B4}"; 14 | 15 | // Copied from EnvDTE.Constants since that type can't be embedded 16 | internal const string VsProjectItemKindPhysicalFile = "{6BB5F8EE-4483-11D3-8BCF-00C04F8EC28C}"; 17 | internal const string VsProjectItemKindPhysicalFolder = "{6BB5F8EF-4483-11D3-8BCF-00C04F8EC28C}"; 18 | } 19 | } -------------------------------------------------------------------------------- /T4Scaffolding.Core/InstallationDummyFile.txt: -------------------------------------------------------------------------------- 1 | This file is added as part of the NuGet package installation process for the scaffolding package. 2 | It should be deleted automatically after installation is completed. If not, you can delete it manually. -------------------------------------------------------------------------------- /T4Scaffolding.Core/Namespaces.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using EnvDTE; 3 | 4 | namespace T4Scaffolding 5 | { 6 | /// 7 | /// Utility method - produces the "Begin Namespace ..." and "End Namespace" lines for VB 8 | /// accounting for VB's "omit default namespace" convention and the possibility of there 9 | /// being no namespace lines required 10 | /// 11 | public static class Namespaces 12 | { 13 | public static string BeginVb(string fullNamespace, string defaultNamespace) 14 | { 15 | var output = NamespaceToOutput(fullNamespace, defaultNamespace); 16 | return string.IsNullOrEmpty(output) ? null : "Namespace " + output; 17 | } 18 | 19 | public static string EndVb(string fullNamespace, string defaultNamespace) 20 | { 21 | var output = NamespaceToOutput(fullNamespace, defaultNamespace); 22 | return string.IsNullOrEmpty(output) ? null : "End Namespace"; 23 | } 24 | 25 | public static string Normalize(string fullNamespace) 26 | { 27 | if (string.IsNullOrEmpty(fullNamespace)) 28 | return null; 29 | return string.Join(".", fullNamespace.Split(new [] { '.' }, StringSplitOptions.RemoveEmptyEntries)); 30 | } 31 | 32 | public static string GetNamespace(string fullyQualifiedTypeName) 33 | { 34 | if (string.IsNullOrEmpty(fullyQualifiedTypeName)) 35 | return null; 36 | if (!fullyQualifiedTypeName.Contains(".")) 37 | return null; 38 | return fullyQualifiedTypeName.Substring(0, fullyQualifiedTypeName.LastIndexOf('.')); 39 | } 40 | 41 | private static string NamespaceToOutput(string fullNamespace, string defaultNamespace) 42 | { 43 | // Sometimes namespaces may be constructed as: defaultNamespace + ".Something" 44 | // Fix up the case where defaultNamespace is blank 45 | if ((fullNamespace != null) && fullNamespace.StartsWith(".")) 46 | fullNamespace = fullNamespace.Substring(1); 47 | 48 | // Degenerate case) 49 | if (string.IsNullOrEmpty(fullNamespace)) 50 | return null; 51 | 52 | // It's possible to disable the default namespace, in which case you get C#-like behavior 53 | if (string.IsNullOrEmpty(defaultNamespace)) 54 | return fullNamespace; 55 | 56 | // There is no namespace line if you're in the default namespace 57 | if (string.Equals(fullNamespace, defaultNamespace, StringComparison.OrdinalIgnoreCase)) 58 | return null; 59 | 60 | // Omit leading default namespace 61 | if (fullNamespace.StartsWith(defaultNamespace + ".")) 62 | return fullNamespace.Substring(defaultNamespace.Length + 1); 63 | 64 | // You're asking for an unrelated namespace, so leave it unchanged 65 | return fullNamespace; 66 | } 67 | } 68 | } -------------------------------------------------------------------------------- /T4Scaffolding.Core/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("T4Scaffolding.Core")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Microsoft")] 12 | [assembly: AssemblyProduct("T4Scaffolding.Core")] 13 | [assembly: AssemblyCopyright("Copyright © Microsoft 2012")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("953dd28d-0bed-478d-86c2-be47bb54fea6")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.2")] 36 | [assembly: AssemblyFileVersion("1.0.0.2")] 37 | [assembly: InternalsVisibleTo("T4Scaffolding.Test")] -------------------------------------------------------------------------------- /T4Scaffolding.Core/ScaffolderAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace T4Scaffolding 4 | { 5 | public class ScaffolderAttribute : Attribute 6 | { 7 | public string Description { get; set; } 8 | 9 | /// 10 | /// If true, the scaffolder will not appear in any of the usual lists of scaffolders, and will only appear 11 | /// when we query for the set of scaffolders that should appear in the GUI. 12 | /// 13 | public bool HideInConsole { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /T4Scaffolding.Core/Scaffolders/CustomScaffolder/DefaultPs1Script.ps1.t4: -------------------------------------------------------------------------------- 1 | <#@ template language="C#" HostSpecific="True" inherits="DynamicTransform" #> 2 | <#@ Output Extension="ps1" #> 3 | [T4Scaffolding.Scaffolder(Description = "Enter a description of <#= Model.Scaffolder #> here")][CmdletBinding()] 4 | param( 5 | [string]$Project, 6 | [string]$CodeLanguage, 7 | [string[]]$TemplateFolders, 8 | [switch]$Force = $false 9 | ) 10 | 11 | $outputPath = "ExampleOutput" # The filename extension will be added based on the template's <#= "<" #>#@ Output Extension="..." #<#= ">" #> directive 12 | $namespace = (Get-Project $Project).Properties.Item("DefaultNamespace").Value 13 | 14 | Add-ProjectItemViaTemplate $outputPath -Template <#= Model.TemplateName #> ` 15 | -Model @{ Namespace = $namespace; ExampleValue = "Hello, world!" } ` 16 | -SuccessMessage "Added <#= Model.Scaffolder #> output at {0}" ` 17 | -TemplateFolders $TemplateFolders -Project $Project -CodeLanguage $CodeLanguage -Force:$Force -------------------------------------------------------------------------------- /T4Scaffolding.Core/Scaffolders/CustomScaffolder/DefaultT4Template.cs.t4: -------------------------------------------------------------------------------- 1 | <#@ template language="C#" HostSpecific="True" inherits="DynamicTransform" #> 2 | <#@ Output Extension="cs.t4" #> 3 | <#= "<" #>#@ Template Language="C#" HostSpecific="True" Inherits="DynamicTransform" #<#= ">" #> 4 | <#= "<" #>#@ Output Extension="cs" #<#= ">" #> 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Web; 9 | 10 | namespace <#= "<" #>#= Model.Namespace #<#= ">" #> 11 | { 12 | public class ExampleOutput 13 | { 14 | // Example model value from scaffolder script: <#= "<" #>#= Model.ExampleValue #<#= ">" #> 15 | } 16 | } -------------------------------------------------------------------------------- /T4Scaffolding.Core/Scaffolders/CustomScaffolder/DefaultT4Template.vb.t4: -------------------------------------------------------------------------------- 1 | <#@ template language="C#" HostSpecific="True" inherits="DynamicTransform" #> 2 | <#@ Output Extension="vb.t4" #> 3 | <#= "<" #>#@ Template Language="C#" HostSpecific="True" Inherits="DynamicTransform" #<#= ">" #> 4 | <#= "<" #>#@ Output Extension="vb" #<#= ">" #> 5 | Namespace <#= "<" #>#= Model.Namespace #<#= ">" #> 6 | Public Class ExampleOutput 7 | ' Example model value from scaffolder script: <#= "<" #>#= Model.ExampleValue #<#= ">" #> 8 | End Class 9 | End Namespace -------------------------------------------------------------------------------- /T4Scaffolding.Core/Scaffolders/CustomScaffolder/T4Scaffolding.CustomScaffolder.ps1: -------------------------------------------------------------------------------- 1 | [T4Scaffolding.Scaffolder(Description = "Creates an entirely new scaffolder with a PS1 script and a T4 template")][CmdletBinding()] 2 | param( 3 | [parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)][string]$CustomScaffolderName, 4 | [string]$Project, 5 | [string]$CodeLanguage, 6 | [string[]]$TemplateFolders, 7 | [switch]$Force = $false 8 | ) 9 | 10 | $templateName = $CustomScaffolderName + "Template" 11 | 12 | # PS1 script 13 | $customScaffoldersPath = [T4Scaffolding.Core.ScaffoldingConstants]::CustomScaffoldersFolderPath 14 | $outputPath = Join-Path (Join-Path $customScaffoldersPath $CustomScaffolderName) $CustomScaffolderName 15 | Add-ProjectItemViaTemplate $outputPath -Template DefaultPs1Script -Model @{ 16 | Scaffolder = $CustomScaffolderName; 17 | TemplateName = $templateName; 18 | } -SuccessMessage "Added scaffolder script '{0}'" -TemplateFolders $TemplateFolders -Project $Project -CodeLanguage "ps1" -Force:$Force 19 | 20 | # T4 template 21 | $outputPath = Join-Path (Join-Path $customScaffoldersPath $CustomScaffolderName) $templateName 22 | Add-ProjectItemViaTemplate $outputPath -Template DefaultT4Template -Model @{ 23 | } -SuccessMessage "Added scaffolder template '{0}'" -TemplateFolders $TemplateFolders -Project $Project -CodeLanguage $CodeLanguage -Force:$Force -------------------------------------------------------------------------------- /T4Scaffolding.Core/Scaffolders/CustomTemplate/T4Scaffolding.CustomTemplate.ps1: -------------------------------------------------------------------------------- 1 | [T4Scaffolding.Scaffolder(Description = "Allows you to modify the T4 template rendered by a scaffolder")][CmdletBinding()] 2 | param( 3 | [parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)][string]$ScaffolderName, 4 | [parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)][string]$TemplateName, 5 | [string]$Project, 6 | [string]$CodeLanguage, 7 | [switch]$Force = $false 8 | ) 9 | 10 | # Ensure we can find a unique scaffolder 11 | $resolvedScaffolder = Get-Scaffolder $ScaffolderName -Project $Project 12 | if (!$resolvedScaffolder) { 13 | Write-Error "Could not find scaffolder '$ScaffolderName'" 14 | return 15 | } elseif ($resolvedScaffolder -is [Array]) { 16 | Write-Error "More than one scaffolder matches the name '$ScaffolderName'" 17 | return 18 | } 19 | 20 | # Find its template 21 | $scaffolderFolder = [System.IO.Path]::GetDirectoryName($resolvedScaffolder.Location) 22 | $sourceTemplateFile = Find-ScaffolderTemplate $TemplateName -TemplateFolders $scaffolderFolder -Project $Project -CodeLanguage $CodeLanguage -ErrorIfNotFound 23 | if (!$sourceTemplateFile) { return } 24 | 25 | # Determine where the output will go in the project, and ensure we're not going to overwrite anything (except if Force is on) 26 | $customScaffoldersPath = [T4Scaffolding.Core.ScaffoldingConstants]::CustomScaffoldersFolderPath 27 | $outputPath = Join-Path (Join-Path $customScaffoldersPath $resolvedScaffolder.Name) ([System.IO.Path]::GetFileName($sourceTemplateFile)) 28 | $existingProjectItem = Get-ProjectItem $outputPath -Project $Project 29 | if ($existingProjectItem -and -not $Force) { 30 | Write-Warning "$outputPath already exists! Pass -Force to overwrite. Skipping..." 31 | return 32 | } 33 | 34 | # Copy the source file to the output location in the project 35 | if ($existingProjectItem) { 36 | $outputPath = $existingProjectItem.Properties.Item("FullPath").Value 37 | Set-IsCheckedOut $outputPath 38 | Copy-Item -Path $sourceTemplateFile -Destination $outputPath -Force 39 | } else { 40 | $outputDir = [System.IO.Path]::GetDirectoryName($outputPath) 41 | $outputDirProjectItem = Get-ProjectFolder $outputDir -Create -Project $Project 42 | $outputDirProjectItem.AddFromFileCopy($sourceTemplateFile) | Out-Null 43 | } 44 | 45 | Write-Host "Added custom template '$outputPath'" -------------------------------------------------------------------------------- /T4Scaffolding.Core/T4Scaffolding.Core.nuspec: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | T4Scaffolding.Core.VS2017 5 | 1.0.1 6 | David Fowler, Scott Hanselman, Steve Sanderson, David Anderson, Cigano Morrison Mendez 7 | T4Scaffolding.Core (Fix VS2017) 8 | A fast and customizable way to build parts of your .NET application via templates 9 | A fast and customizable way to build parts of your .NET application via templates 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /T4Scaffolding.Core/T4Scaffolding.Format.ps1xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | T4Scaffolding.Core.ScaffolderLocators.ScaffolderInfo 5 | 6 | T4Scaffolding.Core.ScaffolderLocators.ScaffolderInfo 7 | 8 | 9 | 10 | 35 11 | 12 | 30 13 | 14 | 15 | 16 | 17 | Name 18 | Description 19 | PackageName 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /T4Scaffolding.Core/ViewScaffolderAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace T4Scaffolding 4 | { 5 | public class ViewScaffolderAttribute : ScaffolderAttribute 6 | { 7 | public string DisplayName { get; set; } 8 | public string LayoutPageFilter { get; set; } 9 | public bool IsRazorType { get; set; } 10 | 11 | public ViewScaffolderAttribute(string displayName) 12 | { 13 | if (string.IsNullOrEmpty(displayName)) 14 | throw new ArgumentException("Value cannot be null or empty", "displayName"); 15 | 16 | DisplayName = displayName; 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /T4Scaffolding.Core/init.ps1: -------------------------------------------------------------------------------- 1 | param($rootPath, $toolsPath, $package, $project) 2 | 3 | function GetLoadedT4ScaffoldingAssemblyVersion() { 4 | try { 5 | return [T4Scaffolding.ScaffolderAttribute].Assembly.GetName().Version 6 | } catch { 7 | return $null 8 | } 9 | } 10 | $t4ScaffoldingAssemblyVersion = GetLoadedT4ScaffoldingAssemblyVersion 11 | 12 | if ($t4ScaffoldingAssemblyVersion -and ($t4ScaffoldingAssemblyVersion -ne "1.0.0.2")) 13 | { 14 | # Prevent the use of scaffolding if you've got the wrong version of T4Scaffolding.dll loaded into your appdomain (we can't unload or update it until VS restarts) 15 | Write-Warning "---" 16 | Write-Warning "A different version of T4Scaffolding is already running in this instance of Visual Studio" 17 | Write-Warning "Please restart Visual Studio to avoid unexpected behavior." 18 | Write-Warning "You won't be able to use scaffolding until you restart Visual Studio." 19 | Write-Warning "---" 20 | if (Get-Module T4Scaffolding) { 21 | # Disable scaffolding as much as possible until VS is restarted 22 | Remove-Module T4Scaffolding 23 | } 24 | } 25 | else 26 | { 27 | # OK, we've got the correct .NET assembly version or none at all (in which case we can load the correct version) 28 | $dllPath = Join-Path $toolsPath T4Scaffolding.dll 29 | $tabExpansionPath = Join-Path $toolsPath "scaffoldingTabExpansion.psm1" 30 | $packagesRoot = [System.IO.Path]::GetDirectoryName($rootPath) 31 | 32 | if (Test-Path $dllPath) { 33 | # Enable shadow copying so the package can be uninstalled/upgraded later 34 | [System.AppDomain]::CurrentDomain.SetShadowCopyFiles() 35 | 36 | # Load the .NET PowerShell module and set up aliases, tab expansions, etc. 37 | Import-Module $dllPath 38 | [T4Scaffolding.NuGetServices.Services.ScaffoldingPackagePathResolver]::SetPackagesRootDirectory($packagesRoot) 39 | Set-Alias Scaffold Invoke-Scaffolder -Option AllScope -scope Global 40 | Update-FormatData -PrependPath (Join-Path $toolsPath T4Scaffolding.Format.ps1xml) 41 | Import-Module -Force -Global $tabExpansionPath 42 | 43 | # Ensure you've got some default settings for each of the included scaffolders 44 | Set-DefaultScaffolder -Name CustomTemplate -Scaffolder T4Scaffolding.CustomTemplate -SolutionWide -DoNotOverwriteExistingSetting 45 | Set-DefaultScaffolder -Name CustomScaffolder -Scaffolder T4Scaffolding.CustomScaffolder -SolutionWide -DoNotOverwriteExistingSetting 46 | } 47 | else 48 | { 49 | Write-Warning ("Could not find T4Scaffolding module. Looked for: " + $dllPath) 50 | } 51 | } -------------------------------------------------------------------------------- /T4Scaffolding.Core/install.ps1: -------------------------------------------------------------------------------- 1 | param($rootPath, $toolsPath, $package, $project) 2 | 3 | # Try to delete InstallationDummyFile.txt 4 | if ($project) { 5 | $project.ProjectItems | ?{ $_.Name -eq "InstallationDummyFile.txt" } | %{ $_.Delete() } 6 | } -------------------------------------------------------------------------------- /T4Scaffolding.Core/uninstall.ps1: -------------------------------------------------------------------------------- 1 | param($rootPath, $toolsPath, $package, $project) 2 | 3 | # Bail out if Set-IsCheckedOut is disabled (probably because you're running an incompatible version of NuGet) 4 | if (-not (Get-Command Set-IsCheckedOut -ErrorAction SilentlyContinue)) { return } 5 | 6 | # Try to delete the solution-level config file, if there is one 7 | if ($project) { 8 | $solutionDir = [System.IO.Path]::GetDirectoryName($project.DTE.Solution.FullName) 9 | $configFile = Join-Path $solutionDir "scaffolding.config" 10 | if (Test-Path $configFile) { 11 | Set-IsCheckedOut $configFile 12 | del $configFile 13 | } 14 | } -------------------------------------------------------------------------------- /T4Scaffolding.NuGetServices/ConsoleInitializer.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.VisualStudio.ComponentModelHost; 2 | using Microsoft.VisualStudio.Shell; 3 | using NuGetConsole; 4 | 5 | namespace T4Scaffolding.NuGetServices 6 | { 7 | internal static class ConsoleInitializer 8 | { 9 | public static void EnsureRunspaceOnCurrentThread() 10 | { 11 | IConsoleInitializer consoleInitializer = GetConsoleInitializer(); 12 | if (consoleInitializer != null) 13 | consoleInitializer.Initialize().Result(); 14 | } 15 | 16 | private static IConsoleInitializer GetConsoleInitializer() 17 | { 18 | try { 19 | var componentModel = (IComponentModel)Package.GetGlobalService(typeof(SComponentModel)); 20 | return componentModel.GetService(); 21 | } 22 | catch { 23 | // e.g., if you're running a version of NuGet that doesn't expose an IConsoleInitializer 24 | return null; 25 | } 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /T4Scaffolding.NuGetServices/ExtensionMethods/PackageExtensions.cs: -------------------------------------------------------------------------------- 1 | using T4Scaffolding.NuGetServices.Services; 2 | 3 | namespace T4Scaffolding.NuGetServices.ExtensionMethods 4 | { 5 | internal static class PackageExtensions 6 | { 7 | public static string GetFullName(this IPackageMetadata package) 8 | { 9 | return package.Id + " " + package.Version; 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /T4Scaffolding.NuGetServices/ExtensionMethods/SolutionExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using EnvDTE; 4 | 5 | namespace T4Scaffolding.NuGetServices.ExtensionMethods 6 | { 7 | internal static class SolutionExtensions 8 | { 9 | /// 10 | /// Get the list of all supported projects in the current solution. This method 11 | /// recursively iterates through all projects. 12 | /// 13 | public static IEnumerable GetAllProjects(this Solution solution) 14 | { 15 | if (solution == null || !solution.IsOpen) 16 | { 17 | yield break; 18 | } 19 | 20 | var projects = new Stack(); 21 | foreach (Project project in solution.Projects) 22 | { 23 | projects.Push(project); 24 | } 25 | 26 | while (projects.Any()) 27 | { 28 | Project project = projects.Pop(); 29 | 30 | if (project.IsSupported()) 31 | { 32 | yield return project; 33 | } 34 | 35 | // ProjectItems property can be null if the project is unloaded 36 | if (project.ProjectItems != null) 37 | { 38 | foreach (ProjectItem projectItem in project.ProjectItems) 39 | { 40 | if (projectItem.SubProject != null) 41 | { 42 | projects.Push(projectItem.SubProject); 43 | } 44 | } 45 | } 46 | } 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /T4Scaffolding.NuGetServices/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("T4Scaffolding.NuGetServices")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Microsoft")] 12 | [assembly: AssemblyProduct("T4Scaffolding.NuGetServices")] 13 | [assembly: AssemblyCopyright("Copyright © Microsoft 2011")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("89b04540-9525-480f-b7fc-53a485826a72")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | 38 | [assembly: InternalsVisibleTo("T4Scaffolding")] 39 | [assembly: InternalsVisibleTo("T4Scaffolding.Test")] -------------------------------------------------------------------------------- /T4Scaffolding.NuGetServices/ScaffoldingNuGetBaseCmdlet.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Management.Automation; 4 | using System.Reflection; 5 | using T4Scaffolding.NuGetServices.Services; 6 | 7 | namespace T4Scaffolding.NuGetServices 8 | { 9 | /// 10 | /// Duplicates the functionality of NuGet.VisualStudio.Cmdlets.NuGetBaseCmdlet so we can follow the same coding patterns without 11 | /// taking an actual binary dependency on a specific version of NuGet.VisualStudio.dll. 12 | /// -- 13 | /// Since we need to issue a PowerShell command to determine the current NuGet "default project", we have to defer initialization 14 | /// of SolutionManager and other services until the cmdlet has entered the ProcessRecord phase. 15 | /// 16 | public abstract class ScaffoldingNuGetBaseCmdlet : PSCmdlet 17 | { 18 | private readonly Lazy _solutionManager; 19 | private readonly Lazy _packageManagerFactory; 20 | private readonly Lazy _packageManager; 21 | 22 | protected ISolutionManager SolutionManager { get { return _solutionManager.Value; } } 23 | protected IPackageManager PackageManager { get { return _packageManager.Value; } } 24 | 25 | protected ScaffoldingNuGetBaseCmdlet(ISolutionManager solutionManager, IVsPackageManagerFactory vsPackageManagerFactory) 26 | { 27 | // Command intrinsics (and hence DefaultProjectName) can't be accessed until the PSCmdlet enters the "ProcessRecord" phase, 28 | // so we have to defer evaluation of the following things until then. To support unit testing, it's possible to override 29 | // their instantiation by passing a non-null instance to the constructor. 30 | 31 | _packageManagerFactory = new Lazy(() => { 32 | return vsPackageManagerFactory ?? new PowerShellPackageManagerFactory(InvokeCommand); 33 | }); 34 | _packageManager = new Lazy(() => { 35 | return _packageManagerFactory.Value.CreatePackageManager(); 36 | }); 37 | _solutionManager = new Lazy(() => { 38 | if (solutionManager != null) 39 | return solutionManager; 40 | 41 | var getProjectResults = InvokeCommand.InvokeScript("(Get-Project).Name").ToList(); 42 | var defaultProjectName = getProjectResults.Count == 1 ? (string)getProjectResults.Single().BaseObject : null; 43 | return new ScaffoldingSolutionManager(defaultProjectName); 44 | }); 45 | } 46 | 47 | protected sealed override void ProcessRecord() 48 | { 49 | try { 50 | ProcessRecordCore(); 51 | } catch (Exception ex) { 52 | WriteError(ex); 53 | } 54 | } 55 | 56 | protected abstract void ProcessRecordCore(); 57 | 58 | protected void WriteError(string message) 59 | { 60 | if (!String.IsNullOrEmpty(message)) { 61 | WriteError(new Exception(message)); 62 | } 63 | } 64 | 65 | protected void WriteError(Exception exception) 66 | { 67 | // Only unwrap target invocation exceptions 68 | if (exception is TargetInvocationException) { 69 | exception = exception.InnerException; 70 | } 71 | WriteError(new ErrorRecord(exception, String.Empty, ErrorCategory.NotSpecified, null)); 72 | } 73 | } 74 | } -------------------------------------------------------------------------------- /T4Scaffolding.NuGetServices/Services/IPackage.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace T4Scaffolding.NuGetServices.Services 4 | { 5 | public interface IPackage : IPackageMetadata 6 | { 7 | } 8 | 9 | public interface IPackageMetadata 10 | { 11 | string Id { get; } 12 | IComparable Version { get; } 13 | } 14 | } -------------------------------------------------------------------------------- /T4Scaffolding.NuGetServices/Services/IPackageManager.cs: -------------------------------------------------------------------------------- 1 | namespace T4Scaffolding.NuGetServices.Services 2 | { 3 | public interface IPackageManager 4 | { 5 | IPackagePathResolver PathResolver { get; } 6 | IPackageRepository LocalRepository { get; } 7 | } 8 | } -------------------------------------------------------------------------------- /T4Scaffolding.NuGetServices/Services/IPackagePathResolver.cs: -------------------------------------------------------------------------------- 1 | namespace T4Scaffolding.NuGetServices.Services 2 | { 3 | public interface IPackagePathResolver 4 | { 5 | string GetInstallPath(IPackage package); 6 | } 7 | } -------------------------------------------------------------------------------- /T4Scaffolding.NuGetServices/Services/IPackageRepository.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | 3 | namespace T4Scaffolding.NuGetServices.Services 4 | { 5 | public interface IPackageRepository 6 | { 7 | IQueryable GetPackages(); 8 | } 9 | } -------------------------------------------------------------------------------- /T4Scaffolding.NuGetServices/Services/ISolutionManager.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Diagnostics.CodeAnalysis; 3 | using EnvDTE; 4 | 5 | namespace T4Scaffolding.NuGetServices.Services 6 | { 7 | public interface ISolutionManager 8 | { 9 | string SolutionDirectory { get; } 10 | 11 | string DefaultProjectName { get; } 12 | Project DefaultProject { get; } 13 | 14 | Project GetProject(string projectName); 15 | 16 | IEnumerable GetProjects(); 17 | 18 | bool IsSolutionOpen { get; } 19 | } 20 | } -------------------------------------------------------------------------------- /T4Scaffolding.NuGetServices/Services/IVsPackageManagerFactory.cs: -------------------------------------------------------------------------------- 1 | namespace T4Scaffolding.NuGetServices.Services 2 | { 3 | public interface IVsPackageManagerFactory 4 | { 5 | IPackageManager CreatePackageManager(); 6 | } 7 | } -------------------------------------------------------------------------------- /T4Scaffolding.NuGetServices/Services/PowerShellPackageManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Management.Automation; 3 | 4 | namespace T4Scaffolding.NuGetServices.Services 5 | { 6 | public class PowerShellPackageManager : IPackageManager 7 | { 8 | private readonly CommandInvocationIntrinsics _commandInvocationIntrinsics; 9 | 10 | public PowerShellPackageManager(CommandInvocationIntrinsics commandInvocationIntrinsics) 11 | { 12 | if (commandInvocationIntrinsics == null) throw new ArgumentNullException("commandInvocationIntrinsics"); 13 | _commandInvocationIntrinsics = commandInvocationIntrinsics; 14 | } 15 | 16 | public IPackagePathResolver PathResolver 17 | { 18 | get 19 | { 20 | return new ScaffoldingPackagePathResolver(); 21 | } 22 | } 23 | 24 | public IPackageRepository LocalRepository 25 | { 26 | get { return new PowerShellPackageRepository(_commandInvocationIntrinsics); } 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /T4Scaffolding.NuGetServices/Services/PowerShellPackageManagerFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Management.Automation; 3 | 4 | namespace T4Scaffolding.NuGetServices.Services 5 | { 6 | public class PowerShellPackageManagerFactory : IVsPackageManagerFactory 7 | { 8 | private readonly CommandInvocationIntrinsics _commandInvocationIntrinsics; 9 | 10 | public PowerShellPackageManagerFactory(CommandInvocationIntrinsics commandInvocationIntrinsics) 11 | { 12 | if (commandInvocationIntrinsics == null) throw new ArgumentNullException("commandInvocationIntrinsics"); 13 | _commandInvocationIntrinsics = commandInvocationIntrinsics; 14 | } 15 | 16 | public IPackageManager CreatePackageManager() 17 | { 18 | return new PowerShellPackageManager(_commandInvocationIntrinsics); 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /T4Scaffolding.NuGetServices/Services/PowerShellPackageRepository.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Management.Automation; 4 | 5 | namespace T4Scaffolding.NuGetServices.Services 6 | { 7 | public class PowerShellPackageRepository : IPackageRepository 8 | { 9 | private readonly CommandInvocationIntrinsics _commandInvocationIntrinsics; 10 | 11 | public PowerShellPackageRepository(CommandInvocationIntrinsics commandInvocationIntrinsics) 12 | { 13 | if (commandInvocationIntrinsics == null) throw new ArgumentNullException("commandInvocationIntrinsics"); 14 | _commandInvocationIntrinsics = commandInvocationIntrinsics; 15 | } 16 | 17 | public IQueryable GetPackages() 18 | { 19 | var getPackageResults = _commandInvocationIntrinsics.InvokeScript("Get-Package"); 20 | return (from package in getPackageResults 21 | select new PowerShellPackage { 22 | Id = (string)package.Properties.First(x => x.Name == "Id").Value, 23 | Version = (IComparable)package.Properties.First(x => x.Name == "Version").Value 24 | }).AsQueryable(); 25 | } 26 | 27 | private class PowerShellPackage : IPackage 28 | { 29 | public string Id { get; set; } 30 | public IComparable Version { get; set; } 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /T4Scaffolding.NuGetServices/Services/ScaffoldingPackagePathResolver.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Linq; 4 | 5 | namespace T4Scaffolding.NuGetServices.Services 6 | { 7 | public class ScaffoldingPackagePathResolver : IPackagePathResolver 8 | { 9 | // Until there's a defined API for enumerating package install directories, we have to 10 | // pass in the root directory from our init.ps1 script. The alternative is replicating 11 | // masses of NuGet's config parsing logic, TFS filesystem, etc. 12 | 13 | private static string _packagesRoot; 14 | 15 | public string GetInstallPath(IPackage package) 16 | { 17 | if (string.IsNullOrEmpty(_packagesRoot)) 18 | throw new InvalidOperationException("Cannot get install path because packages root directory has not been supplied"); 19 | if (!Directory.Exists(_packagesRoot)) 20 | throw new ArgumentException(string.Format("Cannot get install path: Cannot find directory '{0}'", _packagesRoot)); 21 | 22 | return Path.Combine(_packagesRoot, GetPackageDirectory(package)); 23 | } 24 | 25 | public string GetPackageDirectory(IPackage package) 26 | { 27 | return package.Id + "." + package.Version; 28 | } 29 | 30 | public static void SetPackagesRootDirectory(string path) 31 | { 32 | if (string.IsNullOrEmpty(path)) 33 | throw new ArgumentException("SetPackagesRootDirectory: path cannot be null or empty"); 34 | _packagesRoot = path; 35 | } 36 | 37 | public static string InferSolutionDirectory() { 38 | // Normally we can find the solution directory using $dte.Solution.FullName, but if T4Scaffolding is being used as a preinstalled 39 | // NuGet package with a project template, it has to initialize *before* $dte.Solution exists. This is unfortunate. Work around 40 | // by inferring the solution folder from the solution package directory, which is known during initialization. 41 | 42 | return string.IsNullOrEmpty(_packagesRoot) ? null 43 | : Path.GetDirectoryName(_packagesRoot); 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /T4Scaffolding.NuGetServices/Services/ScaffoldingSolutionManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Runtime.InteropServices; 7 | using EnvDTE; 8 | using Microsoft.VisualStudio.Shell; 9 | using T4Scaffolding.NuGetServices.ExtensionMethods; 10 | 11 | namespace T4Scaffolding.NuGetServices.Services 12 | { 13 | public class ScaffoldingSolutionManager : ISolutionManager 14 | { 15 | private readonly DTE _dte; 16 | private readonly string _defaultProjectName; 17 | private Dictionary _projectCache; 18 | 19 | public ScaffoldingSolutionManager(string defaultProjectName) 20 | { 21 | _defaultProjectName = defaultProjectName; 22 | 23 | try 24 | { 25 | _dte = (DTE)Package.GetGlobalService(typeof(DTE)) ?? (DTE)Marshal.GetActiveObject("visualstudio.dte"); 26 | } 27 | catch (COMException exception) 28 | { 29 | if (exception.ErrorCode == -2147221005) 30 | { 31 | _dte= (DTE)Marshal.GetActiveObject("visualstudio.dte.14.0"); 32 | } 33 | else 34 | { 35 | throw; 36 | } 37 | } 38 | 39 | if (_dte == null) throw new InvalidOperationException("Cannot get an instance of EnvDTE.DTE"); 40 | } 41 | 42 | public Project GetProject(string projectName) 43 | { 44 | if (IsSolutionOpen) { 45 | EnsureProjectCache(); 46 | Project project; 47 | _projectCache.TryGetValue(projectName, out project); 48 | return project; 49 | } else { 50 | return null; 51 | } 52 | } 53 | 54 | public IEnumerable GetProjects() 55 | { 56 | if (IsSolutionOpen) { 57 | EnsureProjectCache(); 58 | return _projectCache.Values; 59 | } else { 60 | return Enumerable.Empty(); 61 | } 62 | } 63 | 64 | public string SolutionDirectory 65 | { 66 | get { 67 | if (!IsSolutionOpen || String.IsNullOrEmpty(_dte.Solution.FullName)) { 68 | return null; 69 | } 70 | 71 | return Path.GetDirectoryName(_dte.Solution.FullName); 72 | } 73 | } 74 | 75 | public string DefaultProjectName 76 | { 77 | get { return _defaultProjectName; } 78 | } 79 | 80 | public Project DefaultProject 81 | { 82 | get { 83 | if (String.IsNullOrEmpty(DefaultProjectName)) { 84 | return null; 85 | } 86 | Project project = GetProject(DefaultProjectName); 87 | Debug.Assert(project != null, "Invalid default project"); 88 | return project; 89 | } 90 | } 91 | 92 | public bool IsSolutionOpen 93 | { 94 | get { return _dte.Solution != null && _dte.Solution.IsOpen; } 95 | } 96 | 97 | private void EnsureProjectCache() 98 | { 99 | if (IsSolutionOpen && _projectCache == null) { 100 | // Initialize the cache 101 | var allProjects = _dte.Solution.GetAllProjects(); 102 | _projectCache = allProjects.ToDictionary(project => project.Name, StringComparer.OrdinalIgnoreCase); 103 | } 104 | } 105 | } 106 | } -------------------------------------------------------------------------------- /T4Scaffolding.NuGetServices/Threading/CallStackDepthCounter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.Remoting.Messaging; 3 | 4 | namespace T4Scaffolding.NuGetServices.Threading 5 | { 6 | /// 7 | /// Provides a mechanism to track the depth of a call stack in terms of the number of nested "using(new CallStackDepthCounter) { ... }" statements 8 | /// Uses a combination of techniques to track the depth across thread/appdomain boundaries: 9 | /// * Stores data using CallContext.LogicalGet/SetData to survive normal dispatches to another thread in the same appdomain 10 | /// * Exposes a "Data" property that you can manually copy when using a dispatching mechanism that doesn't respect CallContext (e.g., Microsoft.VisualStudio.Shell.ThreadHelper) 11 | /// * Works after dispatch to a different appdomain, because the "Data" property is a MarshalByRefObject 12 | /// 13 | internal class CallStackDepthCounter : IDisposable 14 | { 15 | private static string callContextKey = Guid.NewGuid().ToString(); 16 | 17 | public class CallContextData : MarshalByRefObject 18 | { 19 | internal int CallStackDepth { get; set; } 20 | } 21 | 22 | public static CallContextData Data 23 | { 24 | get { 25 | if (CallContext.LogicalGetData(callContextKey) == null) 26 | CallContext.LogicalSetData(callContextKey, new CallContextData { CallStackDepth = -1 }); // Start at negative one so the outer frame has depth zero 27 | return (CallContextData)CallContext.LogicalGetData(callContextKey); 28 | } 29 | set { 30 | CallContext.LogicalSetData(callContextKey, value); 31 | } 32 | } 33 | 34 | public CallStackDepthCounter() { Data.CallStackDepth++; } 35 | public void Dispose() { Data.CallStackDepth--; } 36 | 37 | public int Depth 38 | { 39 | get { return Data.CallStackDepth; } 40 | } 41 | } 42 | } -------------------------------------------------------------------------------- /T4Scaffolding.NuGetServices/Threading/OperationDispatcher.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.VisualStudio.Shell; 3 | 4 | namespace T4Scaffolding.NuGetServices.Threading 5 | { 6 | /// 7 | /// DTE operations are very slow when run outside the VS UI thread 8 | /// To speed things up, this class lets us switch back to the UI thread temporarily 9 | /// 10 | public static class OperationDispatcher 11 | { 12 | public static void RunOnUiThread(Action action) 13 | { 14 | RunOnUiThread((Func)(() => { 15 | action(); 16 | return null; 17 | })); 18 | } 19 | 20 | public static T RunOnUiThread(Func func) 21 | { 22 | // We must manually transfer the CallStackDepthCounter value across the thread boundary, because 23 | // CallContext logical data isn't preserved when using Microsoft.VisualStudio.Shell.ThreadHelper 24 | var callStackData = CallStackDepthCounter.Data; 25 | return ThreadHelper.Generic.Invoke(() => { 26 | CallStackDepthCounter.Data = callStackData; 27 | ConsoleInitializer.EnsureRunspaceOnCurrentThread(); // In NuGet 1.2 and later, the UI thread doesn't necessarily have a PowerShell Runspace until we call this 28 | return func(); 29 | }); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /T4Scaffolding.NuGetServices/VsConstants.cs: -------------------------------------------------------------------------------- 1 | namespace T4Scaffolding.NuGetServices 2 | { 3 | internal static class VsConstants 4 | { 5 | // Project type guids 6 | internal const string WebApplicationProjectTypeGuid = "{349C5851-65DF-11DA-9384-00065B846F21}"; 7 | internal const string WebSiteProjectTypeGuid = "{E24C65DC-7377-472B-9ABA-BC803B73C61A}"; 8 | internal const string CsharpProjectTypeGuid = "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"; 9 | internal const string VbProjectTypeGuid = "{F184B08F-C81C-45F6-A57F-5ABD9991F28F}"; 10 | 11 | // Copied from EnvDTE.Constants since that type can't be embedded 12 | internal const string VsProjectItemKindPhysicalFile = "{6BB5F8EE-4483-11D3-8BCF-00C04F8EC28C}"; 13 | internal const string VsProjectItemKindPhysicalFolder = "{6BB5F8EF-4483-11D3-8BCF-00C04F8EC28C}"; 14 | 15 | // All unloaded projects have this Kind value 16 | internal const string UnloadedProjectTypeGuid = "{67294A52-A4F0-11D2-AA88-00C04F688DDE}"; 17 | 18 | // HResults 19 | internal const int S_OK = 0; 20 | } 21 | } -------------------------------------------------------------------------------- /T4Scaffolding.NuGetServices/VsServiceProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace T4Scaffolding.NuGetServices 7 | { 8 | public class VsServiceProvider 9 | { 10 | public static IServiceProvider ServiceProvider 11 | { 12 | get { return Microsoft.VisualStudio.Shell.ServiceProvider.GlobalProvider; } 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /T4Scaffolding.NuGetServices/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /T4Scaffolding.Test/ExampleModels/PersonTemplateModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace T4Scaffolding.Test.ExampleModels 4 | { 5 | [Serializable] 6 | public class PersonTemplateModel 7 | { 8 | public string Name { get; set; } 9 | public int Age { get; set; } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /T4Scaffolding.Test/ExampleScripts/notAScaffolder.ps1: -------------------------------------------------------------------------------- 1 | # Not a scaffolder because it lacks the [T4Scaffolding.Scaffolder()] attribute 2 | param($myparam, $anotherParam) 3 | 4 | return "You entered $myparam then $anotherParam" -------------------------------------------------------------------------------- /T4Scaffolding.Test/ExampleScripts/scaffolderThatAcceptsParameters.ps1: -------------------------------------------------------------------------------- 1 | [T4Scaffolding.Scaffolder(Description = "My description")][CmdletBinding()] 2 | param( 3 | [parameter()]$SomeCustomParam, 4 | [switch]$SomeCustomSwitch, 5 | [string[]]$TemplateFolders 6 | ) 7 | 8 | return "Hello" -------------------------------------------------------------------------------- /T4Scaffolding.Test/ExampleScripts/simpleScaffolder.ps1: -------------------------------------------------------------------------------- 1 | [T4Scaffolding.ControllerScaffolder("My display name", Description = "My description")][CmdletBinding()] 2 | param($myparam, $anotherParam) 3 | 4 | return "You entered $myparam then $anotherParam" -------------------------------------------------------------------------------- /T4Scaffolding.Test/ExampleTemplates/fixedStringTemplate.t4: -------------------------------------------------------------------------------- 1 | <#@ template hostspecific="true" language="C#" inherits="DynamicTransform" #> 2 | Fixed string output from template -------------------------------------------------------------------------------- /T4Scaffolding.Test/ExampleTemplates/personTemplate.t4: -------------------------------------------------------------------------------- 1 | <#@ template hostspecific="true" language="C#" inherits="DynamicTransform" #> 2 | <#@ assembly name="T4Scaffolding.Test" #> 3 | <#= Model.Person.Name #> is <#= Model.Person.Age #> years old. -------------------------------------------------------------------------------- /T4Scaffolding.Test/ExampleTemplates/simpleTemplate.t4: -------------------------------------------------------------------------------- 1 | <#@ template hostspecific="true" language="C#" inherits="DynamicTransform" #> 2 | The name is <#= Model.Name #>. There are <#= Model.Values.Count #> values. -------------------------------------------------------------------------------- /T4Scaffolding.Test/ExampleTemplates/templateWithOutputExtension.t4: -------------------------------------------------------------------------------- 1 | <#@ template hostspecific="true" language="C#" inherits="DynamicTransform" #> 2 | <#@ Output Extension="extensionSpecifiedByOutputDirective" #> 3 | Fixed string output from template with output extension -------------------------------------------------------------------------------- /T4Scaffolding.Test/GetPluralizedWordCmdletTest.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using Microsoft.VisualStudio.TestTools.UnitTesting; 4 | using T4Scaffolding.Cmdlets; 5 | using T4Scaffolding.Test.TestUtils; 6 | 7 | namespace T4Scaffolding.Test 8 | { 9 | [TestClass] 10 | public class GetPluralizedWordCmdletTest 11 | { 12 | [TestMethod] 13 | public void ShouldReturnPluralizedWordForSupportedCulture() 14 | { 15 | var testCases = new Dictionary { 16 | { "cat", "cats" }, 17 | { "City", "Cities" }, 18 | }; 19 | 20 | foreach (var testCase in testCases) { 21 | // Act 22 | var result = new GetPluralizedWordCmdlet { 23 | Word = testCase.Key, 24 | Culture = "en-US" 25 | }.GetResults(); 26 | 27 | // Assert 28 | Assert.AreEqual(testCase.Value, result.Single()); 29 | } 30 | } 31 | 32 | [TestMethod] 33 | public void ShouldReturnUnchangedWordForUnsupportedCulture() 34 | { 35 | // Act 36 | var result = new GetPluralizedWordCmdlet { 37 | Word = "anything", 38 | Culture = "uz-Cyrl-UZ" // Arbitrary CultureInfo name that's not yet supported for pluralization 39 | }.GetResults(); 40 | 41 | // Assert 42 | Assert.AreEqual("anything", result.Single()); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /T4Scaffolding.Test/GetProjectItemCmdletTest.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | using EnvDTE; 4 | using T4Scaffolding.Cmdlets; 5 | using T4Scaffolding.Test.TestUtils; 6 | 7 | namespace T4Scaffolding.Test 8 | { 9 | [TestClass] 10 | public class GetProjectItemCmdletTest 11 | { 12 | [TestMethod] 13 | public void ShouldReturnExistingItem() 14 | { 15 | // Arrange 16 | var solutionManager = new MockSolutionManagerBuilder(new MockProject("myProj", 17 | new MockFolder("someFolder", 18 | new MockFolder("childFolder", new MockItem("someFile.ext")) 19 | ) 20 | )).Build(); 21 | 22 | // Act 23 | var results = new GetProjectItemCmdlet(solutionManager) { 24 | Path = "someFolder\\childFolder\\someFile.ext" 25 | }.GetResults(); 26 | 27 | // Assert 28 | Assert.AreEqual("someFile.ext", results.Single().Name); 29 | } 30 | 31 | [TestMethod] 32 | public void ShouldReturnNothingIfFileNotFound() 33 | { 34 | // Arrange 35 | var solutionManager = new MockSolutionManagerBuilder(new MockProject("myProj", 36 | new MockFolder("someFolder", new MockItem("someFile.ext")) 37 | )).Build(); 38 | 39 | // Act 40 | var results = new GetProjectItemCmdlet(solutionManager) { 41 | Path = "someFolder\\nonExistent.ext" 42 | }.GetResults(); 43 | 44 | // Assert 45 | Assert.AreEqual(0, results.Count()); 46 | } 47 | 48 | [TestMethod] 49 | public void ShouldReturnNothingIfFolderNotFound() 50 | { 51 | // Arrange 52 | var solutionManager = new MockSolutionManagerBuilder(new MockProject("myProj", 53 | new MockFolder("someFolder", new MockItem("someFile.ext")) 54 | )).Build(); 55 | 56 | // Act 57 | var results = new GetProjectItemCmdlet(solutionManager) { 58 | Path = "nonExistent\\someFile.ext" 59 | }.GetResults(); 60 | 61 | // Assert 62 | Assert.AreEqual(0, results.Count()); 63 | } 64 | 65 | [TestMethod] 66 | public void ShouldBeAbleToSpecifyArbitraryProjectName() 67 | { 68 | // Arrange 69 | var solutionManager = new MockSolutionManagerBuilder( 70 | new MockProject("firstProj"), 71 | new MockProject("secondProj", new MockItem("someFile.ext")) 72 | ).Build(); 73 | 74 | // Act 75 | var results = new GetProjectItemCmdlet(solutionManager) { 76 | Path = "someFile.ext", 77 | Project = "secondProj" 78 | }.GetResults(); 79 | 80 | // Assert 81 | Assert.AreEqual("someFile.ext", results.Single().Name); 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /T4Scaffolding.Test/GetProjectLanguageCmdletTest.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using Microsoft.VisualStudio.TestTools.UnitTesting; 4 | using T4Scaffolding.Cmdlets; 5 | using T4Scaffolding.Core; 6 | using T4Scaffolding.Test.TestUtils; 7 | 8 | namespace T4Scaffolding.Test 9 | { 10 | [TestClass] 11 | public class GetProjectLanguageCmdletTest 12 | { 13 | [TestMethod] 14 | public void ShouldReturnLanguageForKnownProjectTypes() 15 | { 16 | var testCases = new Dictionary { 17 | { VsConstants.CsharpProjectTypeGuid, "cs" }, 18 | { VsConstants.VbProjectTypeGuid, "vb" }, 19 | }; 20 | 21 | foreach (var testCase in testCases) { 22 | // Arrange 23 | var solutionManager = new MockSolutionManagerBuilder( 24 | new MockProject("myProj") { Kind = testCase.Key } 25 | ).Build(); 26 | 27 | // Act 28 | var result = new GetProjectLanguageCmdlet(solutionManager).GetResults(); 29 | 30 | // Assert 31 | Assert.AreEqual(testCase.Value, result.Single()); 32 | } 33 | } 34 | 35 | [TestMethod] 36 | public void ShouldReturnNothingForUnknownProjectTypes() 37 | { 38 | // Arrange 39 | var solutionManager = new MockSolutionManagerBuilder( 40 | new MockProject("myProj") { Kind = "someUnknownProjectKind" } 41 | ).Build(); 42 | 43 | // Act 44 | var result = new GetProjectLanguageCmdlet(solutionManager).GetResults(); 45 | 46 | // Assert 47 | Assert.AreEqual(0, result.Count()); 48 | } 49 | 50 | [TestMethod] 51 | public void ShouldBeAbleToSpecifyArbitraryProjectName() 52 | { 53 | // Arrange 54 | var solutionManager = new MockSolutionManagerBuilder( 55 | new MockProject("firstProj") { Kind = VsConstants.CsharpProjectTypeGuid }, 56 | new MockProject("secondProj") { Kind = VsConstants.VbProjectTypeGuid } 57 | ).Build(); 58 | 59 | // Act 60 | var result = new GetProjectLanguageCmdlet(solutionManager) { Project = "secondProj" }.GetResults(); 61 | 62 | // Assert 63 | Assert.AreEqual("vb", result.Single()); 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /T4Scaffolding.Test/GetSingularizedWordCmdletTest.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using Microsoft.VisualStudio.TestTools.UnitTesting; 4 | using T4Scaffolding.Cmdlets; 5 | using T4Scaffolding.Test.TestUtils; 6 | 7 | namespace T4Scaffolding.Test 8 | { 9 | [TestClass] 10 | public class GetSingularizedWordCmdletTest 11 | { 12 | [TestMethod] 13 | public void ShouldReturnSingularizedWordForSupportedCulture() 14 | { 15 | var testCases = new Dictionary { 16 | { "cats", "cat" }, 17 | { "Cities", "City" }, 18 | }; 19 | 20 | foreach (var testCase in testCases) { 21 | // Act 22 | var result = new GetSingularizedWordCmdlet { 23 | Word = testCase.Key, 24 | Culture = "en-US" 25 | }.GetResults(); 26 | 27 | // Assert 28 | Assert.AreEqual(testCase.Value, result.Single()); 29 | } 30 | } 31 | 32 | [TestMethod] 33 | public void ShouldReturnUnchangedWordForUnsupportedCulture() 34 | { 35 | // Act 36 | var result = new GetSingularizedWordCmdlet { 37 | Word = "anything", 38 | Culture = "uz-Cyrl-UZ" // Arbitrary CultureInfo name that's not yet supported for pluralization 39 | }.GetResults(); 40 | 41 | // Assert 42 | Assert.AreEqual("anything", result.Single()); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /T4Scaffolding.Test/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("T4Scaffolding.Test")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Microsoft")] 12 | [assembly: AssemblyProduct("T4Scaffolding.Test")] 13 | [assembly: AssemblyCopyright("Copyright © Microsoft 2010")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("0f1d4b4f-7699-4fa9-bbb8-e7d6a7dab513")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /T4Scaffolding.Test/T4Scaffolding.Test.csproj.vspscc: -------------------------------------------------------------------------------- 1 | "" 2 | { 3 | "FILE_VERSION" = "9237" 4 | "ENLISTMENT_CHOICE" = "NEVER" 5 | "PROJECT_FILE_RELATIVE_PATH" = "" 6 | "NUMBER_OF_EXCLUDED_FILES" = "0" 7 | "ORIGINAL_PROJECT_FILE_PATH" = "" 8 | "NUMBER_OF_NESTED_PROJECTS" = "0" 9 | "SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER" 10 | } 11 | -------------------------------------------------------------------------------- /T4Scaffolding.Test/TemplatingTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.CodeDom.Compiler; 3 | using System.Collections.Generic; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Reflection; 7 | using System.Text.RegularExpressions; 8 | using Microsoft.VisualStudio.TestTools.UnitTesting; 9 | using Microsoft.VisualStudio.TextTemplating; 10 | using T4Scaffolding.Core.Templating; 11 | using T4Scaffolding.Test.TestUtils; 12 | 13 | namespace T4Scaffolding.Test 14 | { 15 | [TestClass] 16 | public class TemplatingTest 17 | { 18 | [TestMethod] 19 | public void ShouldBeAbleToReadDynamicModelProperties() 20 | { 21 | // Integration test to check that the T4 template host can read properties from the DynamicViewModel 22 | 23 | dynamic model = new DynamicViewModel(); 24 | model.Name = "foo"; 25 | model.Baz = 1; 26 | model.A = typeof(string); 27 | model.Values = new List { "a", "b", "c" }; 28 | 29 | var result = ProcessTemplate("simpleTemplate", model); 30 | Assert.AreEqual("The name is foo. There are 3 values.", result); 31 | } 32 | 33 | static string ProcessTemplate(string exampleTemplateName, DynamicViewModel model) 34 | { 35 | var templateQualifiedFileName = ExampleTemplates.GetPath(exampleTemplateName); 36 | 37 | if (!File.Exists(templateQualifiedFileName)) 38 | throw new FileNotFoundException("File not found: " + exampleTemplateName); 39 | 40 | // Read the text template. 41 | string input = File.ReadAllText(templateQualifiedFileName); 42 | 43 | // Eliminate Inherits="DynamicTransform" from template directive 44 | input = Regex.Replace(input, @"\<\#\@\s*\bTemplate\b(.*?\b)?Inherits=""DynamicTransform""\s*(.*?)\#\>", @"<#@ Template $1 $2 #>", RegexOptions.Singleline | RegexOptions.IgnoreCase); 45 | 46 | // Append "Model" property (all example templates are C#) 47 | input += ModelPropertyClassFeatures.ModelPropertySourceForLanguage["cs"]; 48 | 49 | // Transform the text template. 50 | using (var host = new DynamicTextTemplatingEngineHost { 51 | TemplateFile = templateQualifiedFileName, 52 | Model = model 53 | }) { 54 | string output = new Engine().ProcessTemplate(input, host); 55 | if (host.Errors.HasErrors) 56 | throw new TemplateProcessingErrorException(host.Errors); 57 | return output; 58 | } 59 | } 60 | 61 | private class TemplateProcessingErrorException : Exception 62 | { 63 | public CompilerErrorCollection Errors { get; private set; } 64 | 65 | public TemplateProcessingErrorException(CompilerErrorCollection errors) 66 | : base(FormatMessage(errors)) 67 | { 68 | Errors = errors; 69 | } 70 | 71 | private static string FormatMessage(CompilerErrorCollection errors) 72 | { 73 | var message = "One or more template processing errors occurred: " + Environment.NewLine; 74 | message += string.Join(Environment.NewLine, errors.Cast().Select(x => x.ToString())); 75 | return message; 76 | } 77 | } 78 | 79 | } 80 | } -------------------------------------------------------------------------------- /T4Scaffolding.Test/TestUtils/CmdletExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using NuGet.VisualStudio.Test; 5 | using T4Scaffolding.Cmdlets; 6 | 7 | namespace T4Scaffolding.Test.TestUtils 8 | { 9 | // Copied from NuPack.VisualStudio.Test because it's marked "interal" there 10 | internal static class CmdletExtensions 11 | { 12 | public static IEnumerable GetResults(this ScaffoldingBaseCmdlet cmdlet) 13 | { 14 | return GetResults(cmdlet).Cast(); 15 | } 16 | 17 | public static IEnumerable GetResults(this ScaffoldingBaseCmdlet cmdlet) 18 | { 19 | var result = new List(); 20 | cmdlet.CommandRuntime = new MockCommandRuntime(result); 21 | try { 22 | cmdlet.Execute(); 23 | return result; 24 | } catch(Exception ex) { 25 | ex.Data["CmdletOutput"] = result; 26 | throw; 27 | } 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /T4Scaffolding.Test/TestUtils/ExampleScripts.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Linq; 4 | using System.Management.Automation; 5 | using System.Management.Automation.Runspaces; 6 | using System.Reflection; 7 | 8 | namespace T4Scaffolding.Test.TestUtils 9 | { 10 | static class ExampleScripts 11 | { 12 | public static ExternalScriptInfo MakeExternalScriptInfo(Runspace powershellRunspace, string exampleScriptName) 13 | { 14 | var outputDirectory = new Uri(Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase)).LocalPath; 15 | var exampleScriptPath = Path.Combine(outputDirectory, "ExampleScripts\\" + exampleScriptName + ".ps1"); 16 | var cmd = string.Format("Set-ExecutionPolicy -Scope Process -ExecutionPolicy RemoteSigned; Get-Command \"{0}\"", exampleScriptPath); 17 | using (Pipeline pipeline = powershellRunspace.CreatePipeline(cmd)) 18 | { 19 | var results = pipeline.Invoke(); 20 | return results.First().BaseObject as ExternalScriptInfo; 21 | } 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /T4Scaffolding.Test/TestUtils/ExampleTemplates.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Reflection; 6 | using System.Text; 7 | 8 | namespace T4Scaffolding.Test.TestUtils 9 | { 10 | internal static class ExampleTemplates 11 | { 12 | public static string GetPath(string templateName) 13 | { 14 | var outputDirectory = new Uri(Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase)).LocalPath; 15 | return Path.Combine(outputDirectory, "ExampleTemplates\\" + templateName + ".t4"); 16 | } 17 | 18 | public static string GetContents(string templateName) 19 | { 20 | return File.ReadAllText(GetPath(templateName)); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /T4Scaffolding.Test/TestUtils/MockFileSystemExtensions.cs: -------------------------------------------------------------------------------- 1 | using Moq; 2 | using T4Scaffolding.Core.FileSystem; 3 | 4 | namespace T4Scaffolding.Test.TestUtils 5 | { 6 | static class MockFileSystemExtensions 7 | { 8 | public static Mock WithFile(this Mock fileSystem, string fullPath) 9 | { 10 | fileSystem.Setup(x => x.FileExists(fullPath)).Returns(true); 11 | return fileSystem; 12 | } 13 | 14 | public static Mock WithTextFile(this Mock fileSystem, string fullPath, string textContents) 15 | { 16 | fileSystem.Setup(x => x.ReadAllText(fullPath)).Returns(textContents); 17 | return fileSystem.WithFile(fullPath); 18 | } 19 | 20 | public static Mock WithExampleTemplate(this Mock fileSystem, string mockFilePath, string exampleTemplateName) 21 | { 22 | return fileSystem.WithTextFile(mockFilePath, ExampleTemplates.GetContents(exampleTemplateName)); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /T4Scaffolding.Test/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /T4Scaffolding/InstallationDummyFile.txt: -------------------------------------------------------------------------------- 1 | This file is added as part of the NuGet package installation process for the scaffolding package. 2 | It should be deleted automatically after installation is completed. If not, you can delete it manually. -------------------------------------------------------------------------------- /T4Scaffolding/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("T4Scaffolding")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Microsoft")] 12 | [assembly: AssemblyProduct("T4Scaffolding")] 13 | [assembly: AssemblyCopyright("Copyright © Microsoft 2010")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("51582e82-05ae-44b0-a022-086373bff055")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] -------------------------------------------------------------------------------- /T4Scaffolding/Scaffolders/EFDbContext/DbContext.cs.t4: -------------------------------------------------------------------------------- 1 | <#@ Template Language="C#" HostSpecific="True" Inherits="DynamicTransform" #> 2 | <#@ Output Extension="cs" #> 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Data.Entity; 6 | using System.Linq; 7 | using System.Web; 8 | 9 | namespace <#= Model.DbContextNamespace #> 10 | { 11 | public class <#= Model.DbContextType #> : DbContext 12 | { 13 | // You can add custom code to this file. Changes will not be overwritten. 14 | // 15 | // If you want Entity Framework to drop and regenerate your database 16 | // automatically whenever you change your model schema, add the following 17 | // code to the Application_Start method in your Global.asax file. 18 | // Note: this will destroy and re-create your database with every model change. 19 | // 20 | // System.Data.Entity.Database.SetInitializer(new System.Data.Entity.DropCreateDatabaseIfModelChanges<<#= Model.DbContextNamespace #>.<#= Model.DbContextType #>>()); 21 | 22 | } 23 | } -------------------------------------------------------------------------------- /T4Scaffolding/Scaffolders/EFDbContext/DbContext.vb.t4: -------------------------------------------------------------------------------- 1 | <#@ Template Language="C#" HostSpecific="True" Inherits="DynamicTransform" #> 2 | <#@ Output Extension="vb" #> 3 | Imports System.Data.Entity 4 | 5 | <#= T4Scaffolding.Namespaces.BeginVb(Model.DbContextNamespace, Model.DefaultNamespace) #> 6 | Public Class <#= Model.DbContextType #> : Inherits DbContext 7 | 8 | ' You can add custom code to this file. Changes will not be overwritten. 9 | ' 10 | ' If you want Entity Framework to drop and regenerate your database 11 | ' automatically whenever you change your model schema, add the following 12 | ' code to the Application_Start method in your Global.asax file. 13 | ' Note: this will destroy and re-create your database with every model change. 14 | ' 15 | ' System.Data.Entity.Database.SetInitializer(New System.Data.Entity.DropCreateDatabaseIfModelChanges(Of <#= Model.DbContextNamespace #>.<#= Model.DbContextType #>)()) 16 | 17 | End Class 18 | <#= T4Scaffolding.Namespaces.EndVb(Model.DbContextNamespace, Model.DefaultNamespace) #> -------------------------------------------------------------------------------- /T4Scaffolding/Scaffolders/EFDbContext/DbContextEntityMember.cs.t4: -------------------------------------------------------------------------------- 1 | <#@ Template Language="C#" HostSpecific="True" Inherits="DynamicTransform" #> 2 | public DbSet<<#= ((EnvDTE.CodeType)Model.EntityType).FullName #>> <#= Model.EntityTypeNamePluralized #> { get; set; } -------------------------------------------------------------------------------- /T4Scaffolding/Scaffolders/EFDbContext/DbContextEntityMember.vb.t4: -------------------------------------------------------------------------------- 1 | <#@ Template Language="C#" HostSpecific="True" Inherits="DynamicTransform" #> 2 | Public Property <#= Model.EntityTypeNamePluralized #> As DbSet(Of <#= ((EnvDTE.CodeType)Model.EntityType).FullName #>) -------------------------------------------------------------------------------- /T4Scaffolding/Scaffolders/EFRepository/T4Scaffolding.EFRepository.ps1: -------------------------------------------------------------------------------- 1 | [T4Scaffolding.Scaffolder(Description = "Creates a repository")][CmdletBinding()] 2 | param( 3 | [parameter(Position = 0, Mandatory = $true, ValueFromPipelineByPropertyName = $true)][string]$ModelType, 4 | [string]$DbContextType, 5 | [string]$Area, 6 | [string]$Project, 7 | [string]$CodeLanguage, 8 | [switch]$NoChildItems = $false, 9 | [string[]]$TemplateFolders, 10 | [switch]$Force = $false 11 | ) 12 | 13 | # Ensure you've referenced System.Data.Entity 14 | (Get-Project $Project).Object.References.Add("System.Data.Entity") | Out-Null 15 | 16 | $foundModelType = Get-ProjectType $ModelType -Project $Project 17 | if (!$foundModelType) { return } 18 | 19 | $primaryKey = Get-PrimaryKey $foundModelType.FullName -Project $Project -ErrorIfNotFound 20 | if (!$primaryKey) { return } 21 | 22 | if(!$DbContextType) { $DbContextType = [System.Text.RegularExpressions.Regex]::Replace((Get-Project $Project).Name, "[^a-zA-Z0-9]", "") + "Context" } 23 | 24 | $outputPath = Join-Path Models ($foundModelType.Name + "Repository") 25 | if ($Area) { 26 | $areaFolder = Join-Path Areas $Area 27 | if (-not (Get-ProjectItem $areaFolder -Project $Project)) { 28 | Write-Error "Cannot find area '$Area'. Make sure it exists already." 29 | return 30 | } 31 | $outputPath = Join-Path $areaFolder $outputPath 32 | } 33 | 34 | if (!$NoChildItems) { 35 | $dbContextScaffolderResult = Scaffold DbContext -ModelType $ModelType -DbContextType $DbContextType -Area $Area -Project $Project -CodeLanguage $CodeLanguage 36 | $foundDbContextType = $dbContextScaffolderResult.DbContextType 37 | if (!$foundDbContextType) { return } 38 | } 39 | if (!$foundDbContextType) { $foundDbContextType = Get-ProjectType $DbContextType -Project $Project } 40 | if (!$foundDbContextType) { return } 41 | 42 | $modelTypePluralized = Get-PluralizedWord $foundModelType.Name 43 | $defaultNamespace = (Get-Project $Project).Properties.Item("DefaultNamespace").Value 44 | $repositoryNamespace = [T4Scaffolding.Namespaces]::Normalize($defaultNamespace + "." + [System.IO.Path]::GetDirectoryName($outputPath).Replace([System.IO.Path]::DirectorySeparatorChar, ".")) 45 | $modelTypeNamespace = [T4Scaffolding.Namespaces]::GetNamespace($foundModelType.FullName) 46 | 47 | Add-ProjectItemViaTemplate $outputPath -Template Repository -Model @{ 48 | ModelType = [MarshalByRefObject]$foundModelType; 49 | PrimaryKey = [string]$primaryKey; 50 | DefaultNamespace = $defaultNamespace; 51 | RepositoryNamespace = $repositoryNamespace; 52 | ModelTypeNamespace = $modelTypeNamespace; 53 | ModelTypePluralized = [string]$modelTypePluralized; 54 | DbContextNamespace = $foundDbContextType.Namespace.FullName; 55 | DbContextType = [MarshalByRefObject]$foundDbContextType; 56 | } -SuccessMessage "Added repository '{0}'" -TemplateFolders $TemplateFolders -Project $Project -CodeLanguage $CodeLanguage -Force:$Force 57 | 58 | -------------------------------------------------------------------------------- /T4Scaffolding/T4Scaffolding.nuspec: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | T4Scaffolding.VS2017 5 | 1.0.1 6 | David Fowler, Scott Hanselman, Steve Sanderson, David Anderson, Cigano Morrison Mendez 7 | T4Scaffolding (Fix VS2017) 8 | A fast and customizable way to build parts of your .NET application via templates 9 | A fast and customizable way to build parts of your .NET application via templates 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /T4Scaffolding/init.ps1: -------------------------------------------------------------------------------- 1 | param($rootPath, $toolsPath, $package, $project) 2 | 3 | # Bail out if scaffolding is disabled (probably because you're running an incompatible version of T4Scaffolding.dll) 4 | if (-not (Get-Module T4Scaffolding)) { return } 5 | 6 | Set-DefaultScaffolder -Name DbContext -Scaffolder T4Scaffolding.EFDbContext -SolutionWide -DoNotOverwriteExistingSetting 7 | Set-DefaultScaffolder -Name Repository -Scaffolder T4Scaffolding.EFRepository -SolutionWide -DoNotOverwriteExistingSetting -------------------------------------------------------------------------------- /T4Scaffolding/install.ps1: -------------------------------------------------------------------------------- 1 | param($rootPath, $toolsPath, $package, $project) 2 | 3 | # Try to delete InstallationDummyFile.txt 4 | if ($project) { 5 | $project.ProjectItems | ?{ $_.Name -eq "InstallationDummyFile.txt" } | %{ $_.Delete() } 6 | } -------------------------------------------------------------------------------- /Tools/NuPack.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processedbeets/ASP.NET-MVC-Scaffolding/e0a017930e88119aecae98d53240570624f338d1/Tools/NuPack.exe --------------------------------------------------------------------------------