EditVisual Studio Templates and Code Generation
EditS#arp Architecture Project Template for Visual Studio 2008
If setup manually, there are many steps that are needed to start coding your own project based on S#arp Archiecture. To assist, a Visual Studio 2008 template has been included in the downloadable release to greatly simplify this process and get you going very quickly with everything you need. Accordingly, a ready-to-use Visual Studio template and wizard has been made available for immediate use. (If you’d like to see how this was done, you can review the source under /src/SharpArch/SharpArch.VsSharpArchTemplate.) To get going, follow these steps to create your own S#arp Architecture project:
- Close all instances of Visual Studio 2008
- If you haven’t already done so, install the T4Toolbox from http://www.codeplex.com/t4toolbox. This enables Visual Studio with templating capabilities. (This is needed for the CRUD scaffolding generator.) Please note any incompatibilities noted within the section entitled "Installing and Configuring Prerequisites."
- Optionally install the T4 Editor Community Edition from http://www.t4editor.net/downloads.html which will add basic coloring to the templates from within Visual Studio. Or use the free version of Tangible T4 Editor from http://t4-editor.tangible-engineering.com/T4-Editor-Visual-T4-Editing.html. It works for Visual Studio 2008 and Visual Studio 2010.
- Copy "<unzip location>\VisualStudioTemplate \SharpArchApplicationTemplate.zip" to "C:\Documents and Settings\<YOUR USERNAME>\My Documents\Visual Studio 2008\Templates\ProjectTemplates\Visual C#\Web\". (Other locations are also available for organizing your templates; see http://msdn.microsoft.com/en-us/library/y3kkate1.aspx for details.)
- From the same source folder, copy SharpArchApplicationWizard.dll to "C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\"
NOTE: use "C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\IDE" on a 64bit system
- You’re now ready to create your S#arp Architecture project:
- Open Visual Studio 2008
- Select File / New / Project
- Select the project type Visual C# / Web
- Select "S#arp Architecture Application" under "My Templates"
- Enter a project name with no spaces; e.g., Northwind, WickedCool, or OtherProjectName
- Enter the location that will serve as the parent folder of the project; e.g., C:\MyProjects, E:\Dev\AllProjects
- Keep "Create directory for solution" unchecked (it'll work if this is selected but will add an extraneous parent folder)
- Click OK
if the template is not there after you have done the steps you might need to refresh templates in your visual studio use this command line
devenv /installvstemplates
- The generated project does not depend on ASP.NET MVC being installed on the development machine. While this is good for compatibility with multiple versions of MVC, the drawback is that ASP.NET MVC item templates are not available within Visual Studio by default. If you have ASP.NET MVC installed and you’d like to have the item templates available, do the following:
- Using Windows Explorer, browse to the generated project and open <YOUR PROJECT>.Web.csproj with Notepad.
- Insert the following immediately after the opening <ProjectTypeGuids> tag, and before the other GUIDs: "{603c0e0b-db56-11dc-be95-000d561079b0};"
- Save and close the csproj file; you’ll be prompted to reload it in VS.
- Additionally, ASP.NET MVC allows views to be compiled with the remainder of your solution. While this is a terrific benefit, it does add an appreciable amount of time to the compile time. The VS generated project is already preconfigured to support this capability but requires you to turn it on if you’d like it, by doing the following:
- Using Windows Explorer, browse to the generated project and open <YOUR PROJECT>.Web.csproj with Notepad.
- Change “false” to “true” within the MvcBuildViews tag.
- Save and close the csproj file; you’ll be prompted to reload it in VS.
- Create your empty project database, if it doesn’t already exist, and set the connection string within <YOUR PROJECT>.Web/NHibernate.config
- Right click the <YOUR PROJECT>.Web project and select "Set as StartUp Project"
- Click F5 to build and run it!
The generated project has the following directory structure:
/MyProject – Contains MyProject.sln.
/app - Contains the core project layers.
/MyProject.ApplicationServices
/MyProject.Core
/MyProject.Data
/MyProject.Web
/MyProject.Web.Controllers
/build - Empty folder for housing build related stuff.
/lib - Contains the solution items for the deployable application.
/db - Contains database schema information; e.g., the result of scaffolding and/or NHibernate's schema export.
/docs - Project documents.
/logs - Output location for log files.
/tests
/MyProject.Tests
/tools
/lib - Contains the solution items for the tests project and all other non-deployable assemblies.
/CrudScaffolding - Customizable CRUD, scaffolding generation code.
If you use the built in CRUD scaffolding generator, or one supplied by the community, it’s important that your directory structure reflect this.
Finally, the VS project template comes with a number of Fluent NHibernate database conventions. An example DB schema has been added to the S#arp Architecture project's /docs folder to demonstrate the kind of DB naming conventions it expects (which are all configurable).
EditCRUD Scaffolding
CRUD Scaffolding is available and can be used within any project generated using the Visual Studio project template. As noted previously, there is currently an incompatibility with T4 Toolbox and VisualSVN on the same machine; consequently, you cannot have VisualSVN installed on your development machine when using the scaffolding generation. This does not preclude you from having other SVN client applications on your development machine.
Running the scaffolding generates the following resources and moves them to the appropriate project folder.
- \MyProject.Core\<EntityName>.cs: A class inheriting from Entity having the properties designated within the generator command file.
- \MyProject.Tests\MyProject.Core\<EntityName>Tests.cs: An NUnit test class for testing the domain object itself. It’s generated with a comparison test included.
- \MyProject.Web.Controllers\<EntityNamePlural>Controller.cs: A controller for doing full CRUD capabilities for the new domain object.
- \MyProject.Tests\MyProject.Web\Controllers\<EntityNamePlural>ControllerTests.cs: A test fixture containing comprehensive unit tests for the controller.
- \MyProject.Web\Views\<EntityNamePlural>\<EntityName>Form.ascx: A form for collecting domain object information for both the create and edit actions.
- \MyProject.Web\Views\<EntityNamePlural>\Create.aspx: A container page for the creation of a new domain object record. It uses the previously mentioned form to collect the information.
- \MyProject.Web\Views\<EntityNamePlural>\Edit.aspx: A container page for the updating of an existing domain object record. It uses the previously mentioned form to collect the information.
- \MyProject.Web\Views\<EntityNamePlural>\Index.aspx: Shows all of the domain object instances in the database. This page also provides links for viewing, editing and deleting existing records as well as a link to adding a new one.
- \MyProject.Web\Views\<EntityNamePlural>\Show.aspx: Shows the details of a particular domain object record.
Note that this scaffolding generator moves the files to the appropriate location and adds the files to the project file itself; therefore, after generating the files, Visual Studio will prompt you to reload the project files. The scaffolding generator does NOT overwrite any files with the same name. Consequently, you never have to worry about it overwriting your preexisting files. But if you want to recreate a file, you’ll need to first delete it manually.
To run the scaffolding generator for your own S#arp Architecture project, do the following:
- Ensure that you’ve installed the T4Toolbox from http://www.codeplex.com/t4toolbox as instructed in the previous section. This enables Visual Studio with templating capabilities.
- Open your S#arp Architecture project within Visual Studio 2008
- Be sure to Save All (Ctrl+Shift+S) before running the CRUD scaffolding generator. If you do not do this and you have pending changes to any *.csproj, the generator may not successfully add the generated files to the project – you’ll then have to “Include in Project” manually any files that got left out.
- Within the solution explorer, expand the “Code Generation” solution folder and modify the contents of CrudScaffolding/ScaffoldingGeneratorCommand.tt as described in the steps below:
- The CRUD generator will run as soon as the file is saved (yes, I know that’s odd), so make sure the last line is commented while you work:
// generator.Run();
- Pass the name of your Entity to the constructor of EntityScaffoldingDetails. It should be singular and in PascalCase with no spaces. You may include a namespace hierarchy in the domain object name; folders and appropriate namespace settings will be generated, respectively. Example domain object names include "Employee" and "Financial.Costs.LedgerEntry" to include the LedgerEntry domain object within the namespace YourProject.Core.Financial.Costs.
- Add instances of EntityProperty, one for each property on the Entity (not including the Id property). Obviously, delete the few existing properties included for demonstration purposes. Remember, don’t include an Id property as it’ll be included automatically. Please review CrudScaffolding/EntityScaffoldingDetails.tt for a described listing of parameters which the overloaded constructor of EntityProperty can accept. (And yes, I know that it’s a pain not to have intellisence in the generator!)
- Optionally, provide a fourth parameter to the ScaffoldingGenerator constructor found just before the call to the generator.Run(). This optional parameter is an array of ArtifactToGenerate enum values to designate exactly which artifacts will be generated. Allowable enum values are found at the very bottom of CrudScaffolding/ScaffoldingEnums.tt. An example usage to just generate the domain object, the unit tests for the domain object and the class map is:
new ArtifactToGenerate[] {
ArtifactToGenerate.DomainObject,
ArtifactToGenerate.ClassMap
}
- Uncomment the last line,
generator.Run() , and save the file. The file generation will occur automatically. After it has completed, re-comment // generator.Run() to avoid prematurely running it next time you’re modifying this file.
- Review MyProject/logs/CrudScaffoldingog to see what files were created and where they were placed. Look to make sure that all the expected files are showing up in VS; if they’re not, it’s likely because you had pending changes to a *.csproj. In that case, show the hidden files via VS and include the respective file(s) manually into the project.
- If, and only if, you included a namespace (anything before the domain object name), then you must be sure that the "area" for the namespace has been included in MyProject/MyProject.Web.Controllers/RouteRegistrar.cs. It is critically important to note that namespace areas with the greatest number of “tiers” need to be declared before namespace areas with fewer tiers. For example, the namespace “Organization/Department” needs to be declared before the namespace "Organization."
- Add your table to support the Entity to your database.
- Compile the solution and run the unit tests with NUnit…everything should hopefully be passing.
Although you may use data types other than primitives, even collections and associations, when defining your Entity within the ScaffoldingGeneratorCommand.tt file, you may have a few additional steps to take for some properties after the code generation has completed. While the CRUD scaffolding generator is a huge timesaver, it’s not very sophisticated when it comes to dealing with associations or reference data types…the compiler and unit testing will guide you through any additional steps you might have to take after code generation has completed.
Solution for complied errors and runtime errors when running CRUD Scaffolding using T4toolbox
-
Move CrudScaffolding project out of the "Code Generation" folder
-
Replace all the protected override void RenderCore() in the Templates (such as
Templates/Core/DomainObjectTemplate.tt) to 'public override string
TransformText()'
-
Append return this.GenerationEnvironment.ToString(); at the end of public override string
TransformText() method
EditDeveloping Custom Scaffolding
S#arp Architecture scaffolding uses the Visual Studio T4 templating technology for providing a manageable approach to scaffolding generation. Accordingly, for the enterprising developer, it is possible to provide your own scaffolding generator. As mentioned within the previous section, it is necessary to install the T4Toolbox (and the recommended T4 Editor) before developing your own scaffolding generator.
The following steps will guide you through customizing your T4 template generator for your S#arp Architecture project. (Please let
Billy McCafferty know if you do so, as I’d love to hear about the approaches that others are taking.)
To customize the templates for your needs, it’s simplest to modify the existing templates found under the CrudScaffolding/Templates folder within Visual Studio. Care needs to be taken if you add any new templates, as described below.
Adding New Template Files It’s advisable that each template be added to its own template class file. To create your templates:
- Right click the folder you’d like to add the template to and select Add / New Item...
- In the Add New Item dialog, select Visual C# Items / Code Generation / Template.
- Provide a name for your template that describes its purpose; something similar to the final name is appropriate. For instance, if the rendered controller will be called CustomerController.cs, then a good name for the template is DomainObjectControllerTemplate.tt.
- Unfortunately, Visual Studio attempts to render template files as soon as they’re added. Since it’s preferred to leave the rendering of the template up to the generator (discussed next), you’ll want to detach the template from the built-in template renderer. To do so, right click the newly added template and select Properties. Set the value of the "Custom Tool" property to a blank field and save the change.
- Change the template class to inherit from BaseTemplate and add a constructor to accept the appropriate arguments and pass them to the base template’s constructor. It’s simplest to follow an already existing example; take a look at the templates provided within the SharpArch.Scaffolding project for good examples to learn from.