Scaffolding Services and Controllers
Last Updated: February 2021
Scaffolding Overview
Scaffolding is a technique for creating database-backed applications. It can be used to easily and quickly generate services and controllers in a project based on existing items and thus enjoys a variety of benefits:
Collaboration friendliness;
Reduced repetitive work;
Enhanced development efficiency (a developer doesn’t have to build a project from scratch).
SnapDevelop allows you to scaffold controllers and services based on .NET DataStore or SqlModelMapper models. This document describes the scaffolding settings, and walks you through the process of scaffolding services and controllers in SnapDevelop.
Accessing Scaffolding Functionality
SnapDevelop provides the following scaffolding options:
- Scaffold Controller: Generates controllers from services.
- Scaffold Service and Controller: Generates controllers and services from models.
The scaffolding options are available for all .cs files and folders containing .cs files in a project. Make sure you choose the appropriate items (models or services) to scaffold on. Chances are that you can use a wrong option to generate scaffolded items (service and/or controller) in the target project but such items would fail to work.
Scaffolding Templates
System Scaffolding Templates
Scaffolding templates are essential for the scaffolding feature. There are a number of system scaffolding templates to choose from in the current version.
System Template | Description |
---|---|
.NET DataStore Service related | |
Repository_Pattern_Service_DataStore_for_PBClient | Generates services that perform PB-style DataStore operations (including Retrieve and Update) on .NET DataStore models. |
Repository_Pattern_Service_DataStore_for_NonPBClient | Generates services that perform standard C# operations (including Retrieve , Create, RetrieveOne, Update and Delete) on .NET DataStore models. |
Repository_Pattern_Service_DataStore_for_AnyClient | Generates services that perform both PB-style DataStore operations and standard C# operations on .NET DataStore models. |
SqlModelMapper Service related | |
Repository_Pattern_Service_SqlModelMapper | Generates services that perform standard C# operations on SqlModelMapper models. |
Controller related | |
Controller_based_on_service | Generates controllers based on services. |
Viewing and Editing Scaffolding Templates
You can view and edit the scaffolding templates in the folder <SnapDevelop_install_path>\Appeon\SnapDevelop 2019 R3\modules\SnapDevelop.Scaffolding\Templates.
Each *.template file in the folder refers to the configuration of a template. For example, ServiceToController.template.
In the file:
- ID: The template ID. It must be unique for each template.
- Name: The name option to represent the template in the Scaffolding window and Scaffolding option settings.
- Template Items: The actual template to be used. Note that the file and folder are specified with the relative path of the current template directory.
- Package: The NuGet package that must be installed for the item generated based on the template to work properly.
- ParsingRules: The parsing rules used for parsing the source items.
- (For controller templates only) ParentTemplates: The IDs of the associated service templates. When the ID of a service template is specified for a controller template, after you have used the service template for scaffolding services, you will be able to select the controller template for scaffolding controllers based on the services.
- (For service templates only) SuperClass Related Settings (such as IsEnableSuperClass, DefaultSuperClassName): Defines whether to generate base class for the target services, and what are the default base class name, and templates to use. Note that you shall create the corresponding base class templates in the template folder and also the template\Impl folder.
It is recommended that you do not change the configuration and design of system templates. However, you can create your own scaffolding templates. For more information, see Adding Scaffolding Templates.
Adding Scaffolding Templates
You can create your own scaffolding templates. When you add a new scaffolding template, add it to the folder <SnapDevelop_install_path>\Appeon\SnapDevelop 2019 R3\modules\SnapDevelop.Scaffolding\Templates. You can copy an existing template file and customize it to your needs.
Configuring Scaffolding Settings
Personalizing General Settings
You can personalize general settings on Tools > Options > Scaffolding.
Selecting Namespace Style
Under Scaffolding > General, you can specify the namespace style for classes in the generated services/controllers. The following namespace styles are available:
Root namespace only
If you select this option, the generated services/controllers use the root namespace you specify in the Namespace setting for the target service(s)/controller(s).
For example, if you set the Namespace field to demo_scaffold1.Services or demo_scaffold1.Controllers when Specifying Scaffolding Options, the namespace declaration in the generated service/controller will be similar to the following:
namespace demo_scaffold1
Full namespace
If you select this option, the namespace in the generated services/controllers will contain both the root namespace and the namespace path, which means that with the above example, the namespace declaration in the generated service will be similar to the following:
namespace demo_scaffold1.Services
And the namespace declaration in the generated controller will be similar to the following:
namespace demo_scaffold1.Controllers
Parsing Rules Settings
Under Scaffolding > Parsing Rules, you can specify how the scaffolding function parses and gets the classes from the source items. Note that you can only define parsing rules for user-defined scaffolding templates.
When Scaffolding Based on a User-Defined Template
At the first step, you need to select a user-defined scaffolding template first. The configured parsing rule will only work for the currently selected template. You can specify different parsing rules for different templates. NOTE: You cannot edit parsing rules for system templates.
Specify Classes and Class Attributes to be Parsed
Get classes by keyword means that the scaffolding function will identify classes from the source items by the keyword Interface, or Class, or both.
Class(es)/Class attribute(s) means that the scaffolding function will identify classes from the source items by the class name or class attributes.
- If you want to parse all classes and/or class attributes in your program, you can select the Class(es) check box and then the Class attribute(s) check box, and leave the input box empty.
- If you want to parse some of the classes and/or class attributes in your program, you can select the Class check box and then the Class attribute(s) check box, and specify the class(es)/class attribute(s) in the input box.
- If you select neither the Class(es) nor the Class attribute(s) check box, no class or class attribute will be parsed.
Specifying Scaffolding Options
When you select Scaffold Controller or Scaffold Service and Controller for an item in the Solution Explorer, the Scaffolding page opens where you can specify options for generating services and controllers.
Options for Generating Services
The Generate Service(s) options are available only when you select Scaffold Service and Controller for an item in the Solution Explorer.
- Model: Select the type of model that you are scaffolding service(s) from in the list.
- Template: Select a template from the list. For more information about the scaffolding templates, see Scaffolding Templates.
- Method: Select to generate asynchronous or synchronous methods. To generate asynchronous methods, make sure the NuGet packages your project includes have been upgraded to the required version:
Packages | Required Versions |
---|---|
SnapObjects (SnapObjects.Data and SnapObjects.Data.AspNetCore) | 3.0.0 or higher |
.NET DataStore (DWNet.Data and DWNet.Data.AspNetCore) | 3.0.0 or higher |
PowerScript Migrator Framework (PowerScript.Bridge) | 1.0.3 or higher |
When you scaffold controllers from services, the scaffolding function will check whether a method in the service is asynchronous or synchronous, and directly generate asynchronous controllers from synchronous methods, and synchronous controllers from synchronous methods.
- Project: Select from the list the project in which you want to generate the target services.
- Subfolder: Specify the folder where you want to generate the target services. You can select a folder from the list, or choose New Folder to create a new one.
- Namespace: Designate the namespace in the target services. To select a namespace style, see Selecting Namespace Style.
- DataContext: Specify the data source that the target service will use. You can select one from the list or choose New DataContext to create a new one. If the newly created DataContext doesn't appear in the list, click Refresh to update the list.
- Base Class: Specify whether to generate a base class for the target service. You can select None to skip generating a base class, or specify the base class to use, or select New Base Class to create a new base class. As indicated in the field name, if you specify a base class that already exists in the current project, the base class can be directly used for the target services; if you specify a base class that does not exist yet, the base class will first be created, and then will be used for the target services. The template used for creating a base class is stored in the same folder with the service templates. For more information, see Viewing and Editing Scaffolding Templates. NOTE: With the “Repository_Pattern_Service_DataStore_for_PBClient” scaffolding template, if a DataStore model does not contain any [Key] attribute (the model is not updatable), no base class will be created for the model despite the base class settings, because the base class defined in the template is not applicable to non-updatable DataStore models.
Options for generating controllers
- Template: Select a template from the list. For more information about the scaffolding templates, see Scaffolding Templates.
- Project: Select from the list the project in which you want to generate the target controllers.
- Subfolder: Specify the folder where you want to generate the target controllers. You can select a folder from the list, or choose New Folder to create a new one.
- Namespace: Designate the namespace in the target controllers. To select a namespace style, see Selecting Namespace Style.
- Set how to add method attributes: These settings allow you to define a set of attributes for the methods in the controllers. For each listed method attribute, specify the method name to which you want to add the method attribute.
Note that if a method is not covered in the setting, scaffolding will decide which method attribute to add for it by checking the parameter of the method:
- If the method has no parameter, the [HttpGet] method attribute will be added to it by default;
- If the method contains one or more parameters with a non-basic C# type, the [HttpPost] method attribute will be added to it by default.
Specifying Scaffolding Source and Target Items
The system templates use the default parsing rules. If you have selected a user-defined template, you can configure the parsing rules before you specify the scaffolding source. The parsing rules filter out what source items you can select from. For more information about the parsing rules, see Parsing Rules Settings.
If Files Already Exist
This setting determines what to do if the files to add for the scaffolded items already exist in the target folder. You can select Overwrite to replace the existing files with the newly generated files, Increment the file name to increment the file names when saving the files, or Skip the file to retain the existing files.
Scaffolding Tutorials
Generating Controllers and Services from Models
The followings guide you through the process of generating controllers and services based on a .NET DataStore model.
Step 1: Building a Model
A C# model in SnapDevelop is created by converting a DataWindow from PowerBuilder IDE.
To build DataWindow in PowerBuilder, and then convert it in SnapDevelop:
- Start PowerBuilder and create a template application with no database connection by right-clicking MyWorkspace and select New >Target >Template Application. For more information, refer to Create a target.
In PowerBuilder, add a new Grid DataWindow that maps to the intended database by clicking New button in the PowerBar, and then select DataWindow >Tabular. Before moving to the next step, you shall save your DataWindow file. For more information, refer to Create and preview a new DataWindow object.
Open your solution in SnapDevelop, right-click the on the solution name, and select Open PB Workspace to open your workspace.
In SnapDevelop, expand the loaded workspace, right-click the DataWindow file and select Convert DataWindow to C# Model. For more information, refer to Add a .NET DataStore Model section of CRUD Operations with .NET DataStore.
Step 2: Configuring Settings for Target Service and Controller
After you right-click the Models which you intend to scaffold on under Solution Explorer, and select Scaffold Controllers and Services, you see the scaffolding settings page. For more information, see Configuring Scaffolding Settings.
Step 3: Exporting Scaffolded Services and Controllers
When you have properly configured scaffolding settings, click Generate to export the scaffolded items to the designated folder in the target project. During the scaffolding process, you may be prompted whether to install the required NuGet packages.
After the scaffolding process is complete, you can check the corresponding folder in the target project to see if the scaffolded items are generated successfully.
Generating Controllers from Services
The followings guide you through the process of generating controllers and services based on a service.
Step 1: Building a Service
A service is responsible for retrieving and creating data models from the data source, based on your business logic. A service normally separates its interface from its implementation of that interface. The interface contains only the declaration of the methods, properties and events. Please note that scaffolding controller is completely based on the existing interface of services.
Follow these steps to build a service of a Web API Project including interfaces and implementations:
Build a Web API project:
In SnapDevelop, from the File menu, select File > New > Project…, select ASP.NET Core Web API. Name the project and click OK.
Create an empty Services folder:
- Right-click the Web API project and select Add > New Folder. Name the folder Services.
Add implementation files and implement the methods of services:
(You can choose to do this step either before or after scaffolding controllers)
Right-click the Web API project and select Add > New Folder. Name the folder (e.g., Impl).
Create classes by right-clicking the sub-folder you just created, select Add > Class. Name it (e.g., DepartmentService.cs) and click OK.
Complete the implementation of classes you build. (You can do this step either before or after scaffolding controllers because controllers are generated by scaffolding on interfaces of a service. )
Add an interface and declarations:
Right-click the Services folder and select Add > Interface. You may name it with a capital “I” following the corresponding implementation Class name to differentiate interface classes from the implementation classes (e.g., IDepartmentService.cs,) and click OK.
Add declarations of methods, properties and events.
After the service building process is complete, the Services folder including interfaces and implementation classes are added into your project. For more information about building a Web API project, refer to Create a Web API Project.
Step 2: Configuring Settings for Target Controller
After you right-click the intended Services to scaffold on under Solution Explorer, and select Scaffold Controllers, you see the scaffolding settings page. For more information, see Configuring Scaffolding Settings.
Step 3: Exporting Scaffolded Controllers
When you have properly configured scaffolding settings, click Generate to export the scaffolded items to the designated folder in the target project. During the scaffolding process, you may be prompted whether to install the required NuGet packages.
After the scaffolding process is complete, you can check the corresponding folder in the target project to see if the scaffolded items are generated successfully.