So you've created a design, and used the code generation feature to produce the starting code for your first
solution. But, er, now what?
Remember that the purpose of code generation is to give you a quickstart to development. You should be mindful that the generated code will need to be customised - it isn't going to execute yet. This tutorial aims to explain some of the steps you might need to take to convert what has been generated into a working application that compiles and executes.
It is difficult to explain all of the steps exactly, as your design will differ from others. The decisions you have made in the design process have made your solution different from everything else - that's what makes it your design. However, if you have used one of the built-in templates then the steps you might need to take will be roughly similar.
This tutorial is based upon the assumption that you used the Blazor Server solution template for CSLA. However, if you have created a C# solution, then most of the following steps are likely to have some relevance.
The tutorial also assumes that you use Visual Studio for development. Other development tools are available, but the tutorial refers to VS as this is both the most common IDE and the one I use myself.
Step 1 - Add the projects to the solution
When you open the solution in Visual Studio or similar, you will find that it's just an empty solution, as if the generation process didn't work at all. However, don't panic, this is expected.
Visual Studio solution files are quite simple in their operation. No assumptions are made about what they should contain - there is no 'globbing' to automatically include projects in subfolders, like there is with the new SDK-style .NET projects. This is intentional, as globbing might not do what you want. It is your choice as to how you structure your solution; you may choose to put one or more projects into solution folders to make the solution easier to navigate.
Whatever you choose, we manually structure our solution in this step by adding the projects the way we want them.
Create any solution folders you know you want first. However, if you want to keep things simple, you can just add the projects to the root of the solution for now and come back to moving them into subfolders later.
In Solution Explorer, right-click the empty solution and choose 'Add' and from the submenu 'Existing Project ...' We are greeted by a dialog that allows us to browse for the project file to add, which you should find in one of the subfolders under the main solution folder. However, this does depend on what locations you specified when you set up the projects as part of the design process, so check the design if you are unsure where to look.
Repeat this step for each of the projects in the solution.
Step 2 - Add inter-project references
Each project currently lives in splendid isolation, totally unaware of the existence of the others. However, the generated code expects that certain inter-project relationships to be in place, so we need to fix that now.
In Visual Studio's Solution Explorer, open one of the projects using the twistie and right-click on the Dependencies node. Choose the 'Add Project Reference ...' menu option. A list of projects is shown, and we can check a checkbox next to those that we want to reference.
We are going to repeat this for each of the projects. For the standard solution structure, here are the project references required:
- Blazor Server references UI Orchestration, Data Access
- UI Orchestration references Object Library
- Data Access references Object Library (note the inversion of control here, an intentional architectural practice)
- Data Storage, if you created it, is a standalone project defining the database structure, which need not reference anything else
Step 3 - Resolve missing namespaces
There is code in some parts of the solution that references items in other namespaces that now need to be resolved. In Visual Studio, use the Error List window to find unrecognised types and resolve the namespaces. There is usually a tooltip that can do this; highlight a reference to an unrecognised type and press Control + . to show suggestions.
The exact number of issues to be resolved is likely to vary based on your design, but here are common issues that you might encounter:
- Each repository in the Data Access project references a contract that is defined inside the Object Library project (or a separate project if you chose to do that instead) so each repository class will need to have a using statement for the namespace in which the contract is defined
- Each CSLA class references the data access contracts for that type, so they too needs using statements for that namespace
- Each ViewModel references types in the Object Library project, so they need using statements for the namespace in which the appropriate classes are defined
- By default, each ServiceCollectionExtensions class is defined in the Microsoft.Extensions.DependencyInjection namespace. These refer to types in their same assembly but defined within the default assembly namespace, so they need to be resolved
- In the Blazor Server project, you can add using statements for items from the Object Library, UI Orchestration layer, plus the Components and Components.Shared namespaces for the Blazor Server project, to the _Imports.razor file in the root. Creating an _Imports.razor file specific to a component subfolder is an alternative design you could consider for a larger application.
Step 4 - Fix Razor edit component markup if required
The current Razor component templates assume that all properties of an object can be edited using an InputText component. However, in reality different data types are edited using different input components. As a result, you may need to change the user interface definition to use alternative input components. For example, if you have an integer Id property as a foreign key to another data structure, that either needs to be edited using an InputNumber component, or changed to use an option dropdown or radiobutton component instead
Step 5 - Complete outstanding TODO tasks
Some generated code contains hints to other work you may need to do to finish the code. Use Visual Studio's Task List window ('View' - 'Task List' menu option) to find the outstanding TODO task items, and consider their suggestions. You either need to do some work as they suggest, or delete the TODO from the comment (or the comment in its entirety) to indicate that the review of the suggestion is complete. This ensures other suggestions can be more easily found in future.
Step 6 - Set the connection string
The Blazor Server project contains an appsettings.Development.json file containing a connection string. At runtime, the default data access code uses the generated ConnectionManager class to request the correct connection string by name. Make sure that the name of the connection string matches the name being requested; normally I use the name of the database, but any string will do. It just needs to be the same string in the code and the config.
As well as setting an appropriate name for the connection string so that it can be discovered correctly, you also need to set up the connection string to access the correct database on the correct database server instance. Using connection information that grants the minimum permissions with which the application can run is a recommended practice, but the details of this approach are beyond the scope of this tutorial.
If you chose to use a different data access technique than the default, this step may vary.
Step 7 - Change navigation if required
If you want to keep the default navigation scheme to test your application, then you may want to add links to it that provide easy access to the functional elements of your design. This is entirely optional and may not be worth doing if you intend to use a different navigation scheme in the future.
If you didn't change this part of the design, the default navigation is defined in the NavMenu.razor component in the Components\Shared subfolder of the Blazor Server project. Copy and paste the markup for the existing link to add new links.
Change the text of the link as well as the value of the href attribute to specify to where to navigate. Remember that the href value should be almost, but not quite, the same as the value in the @page directive of the component to which you want to navigate. The @page directive must have a leading forward slash, but the value of the href attribute of a NavLink component does not. This is a slight inconsistency in Blazor that it is easy to forget, but may cause your navigation to misbehave.
Remember too that you should delete the Match attribute from the new links created using copy and paste; this attribute should be defined on only one of the items in the menu.
Step 8 - Set the startup project
By default, Visual Studio sets the first project you added to the solution as the startup project. If this wasn't the Blazor Server project then when you try to run the solution in VS, the solution won't start.
Right-click the Blazor Server project and choose 'Set as Startup Project' to indicate to Visual Studio that this is your intended application entry point.
Step 9 - Build the startup project
At this point, you should try to build the startup project, or the solution as a whole if you prefer. You may get some build errors that are specific to your design. Sadly, I can't help you much with those; hopefully the problems will be reasonably self-evident!
Iterate round the build & fix cycle to resolve all of the remaining issues. By the end of this step, we want a Blazor Server project that is built and ready to go - but wait! We're not quite there yet.
Step 10 - Add all of the generated files to the Data Storage project
If you used the default Data Storage project to define the structure for a SQL Server database, you will find this project to be empty at this stage. SQL Data Projects still use the old project style, rather than the new SDK-style projects used for other project types. This old project style does not use globbing to recognise the files that are intended to be included within it; instead, each requires its own entry in the project file. We need to add the generated files to the project now.
In Solution Explorer, highlight the Data Storage project. Click the 'Show All Files' button on the toolstrip at the top of the Solution Explorer window; this expands the view of the tree to show any files that are not part of the project. Right-click each file with a .sql extension and choose the 'Include in Project' option from the submenu to include it. Note that Visual Studio supports multiselect in this window, so you can use Shift + click and Control + click to multiselect, making this process easier.
Remember to go through all of the subfolders to find all of the files with a .sql extension. The subfolders are used to separate the definitions for easier navigation.
You may wish to turn off the 'Show All Files' option once you have finished, so that you do not see folders containing build artefacts at a later date.
Step 11 - Verify the Data Storage definition
If you used the default Data Storage project to define the structure for a SQL Server database, you should check that the data structure as defined is how you want it to be. At the moment, DesiGen does not support defining indexes, foreign keys or other constraints as part of the design. As a result, you should take time at this point to set up the necessary constraints and indexes.
Constraints
Define constraints for all foreign keys, and acceptable field values where foreign keys are not available, to ensure the data integrity of your system is enforced within the database. This helps identify bugs in your code, and avoids corruption of your data if you run faulty scripts against the database.
Indexes
Carefully consider the data access of the tables that have been, and whether the WHERE clauses that will be executed on a regular basis will make use of the indexes that exist at the moment. Create all of the appropriate indexes to cover all foreign key constraint checks and all of the regular WHERE clauses that will be used.
Step 12 - Publish the Data Storage project
If you used the default Data Storage project to define the structure for a SQL Server database, you now need to set up the database with that definition. Visual Studio can do this for you. Right-click on the Data Storage project and choose 'Publish'. Set the connection string by clicking 'Edit ...' and set the connection string that Visual Studio will use to make structural changes to your database. Remember that a high level of permissions are required to make database schema changes, so this connection string is likely to be different to the one you use to run your application on a day to day basis.
Create yourself a profile that you can easily reuse in this dialog by clicking 'Save Profile As ...' Follow the process defined by the UI to save the setup to disk so you can easily repeat the publishing step if you change the database definition as part of a separate design.
Once the connection to the database is ready, click the 'Publish' button to push the definition to the database. Publishing compares the existing definition with the required definition, and applies the necessary alterations.
Step 13 - Run the application
Running your application should result in a browser window firing up that starts your application.
Test and enjoy! :-)