Code generators

   —   

Do you want to work with the page, custom table and biz form data in API using strongly typed objects? Or use strongly typed views in MVC? Then read this article to learn more!

Hi everyone, today we are going to explore the new possibility of working with general data containers using strongly typed objects.

Kentico contains several types of data containers that you can use to store data. Among these are:

  • Page data (TreeNode container)
  • Custom tables (CustomTableItem container)
  • Forms (BizFormItem container)

Each of these data containers can store data collections of various object types. This means, for example, that the TreeNode object can carry data for all page types (Article, News, etc…). However, the object doesn’t know anything about the data members stored inside. So whenever you need to access specific data for a certain Page type property in code, you need to get it using the GetValue(“<propertyName>”) method. This can be inconvenient for developers, as you have to know the exact name of the property as well as its type.

To address this, Kentico 8.1 comes with a new feature called Code generators.

The name of the feature should be self-explanatory :-). You can use it to generate C# code for classes which represent specific types of the general data containers (pages, custom tables, biz forms). This generated class contains all the fields that you defined as properties.

Here is an example of the generator for the News page type:

code_tab_news_page_type.png

Working with code generators

I am going to demonstrate working with the generated code on page type objects. The same also applies to custom tables and forms.

Class generation

  1. Create a custom Page type.
  2. Include the file generated in the Code tab in your solution. Based on your scenario, you can include the file in:
    1. CMSApp_MVC/Models
    2. App_Code (web site installation)
    3. Libraries / other location
  3. (Optional) If you want to use the code files in a separate library or external application, allow the system to detect the generated classes in a custom assembly. Add the 'AssemblyDiscoverable' assembly attribute in the library/application project's AssemblyInfo.cs file:

    using CMS; ... [assembly: AssemblyDiscoverable]

     

  4. Use the generated properties in your code.
  5. Build your solution.

Data retrieval

We have also extended our data providers to be able to retrieve these strongly typed objects.

Page type example

The following example demonstrates how you can retrieve data for the News page type. If you look closer, you can see that I have used DocumentQuery API for retrieving data.

// Get news pages InfoDataSet<News> pages = DocumentHelper.GetDocuments<News>() .Path("/News", PathTypeEnum.Children) .OnCurrentSite() .TypedResult; // Get a news page News page = DocumentHelper.GetDocuments<News>() .Path("/News/" + aliasPath) .OnCurrentSite() .FirstObject; string title = page.NewsTitle;


You can find working examples for the News page type in the sample MVC News controller in the CMSApp_MVC project.

Custom table example

// List var items = CustomTableItemProvider.GetItems<SampleTableItem>().TypedResult; // Single item var item = CustomTableItemProvider.GetItem<SampleTableItem>(id);

Form example

// List var items = BizFormItemProvider.GetItems<ContactUsItem>().TypedResult; // Single item var item = BizFormItemProvider.GetItem<ContactUsItem>(id);

Customizing generated classes

We do not recommend modifying the classes generated by the generators as they contain object properties only. The classes are generated as partial classes. This means that you can extend them in your custom code. Using this approach, you will avoid having to merge custom changes made to the generated code. You would have to do this every time the object's properties change and you'd have to generate the class again.

Generated class

public partial class News : TreeNode { #region "Properties" /// <summary> /// News Title. /// </summary> [DatabaseField] public string NewsTitle { ...

Extended class

public partial class News : TreeNode { public void LoadSampleData() { NewsTitle = "Kentico 8.1 is out!"; NewsReleaseDate = new DateTime(2014, 8, 22); } }

MVC

I believe that you will find strongly typed objects useful in web parts, data connectors and other parts of your projects. Especially MVC developers are now able to easily create models for strongly typed views. Just one advice: do not use the generated classes as MVC models directly. They are still the same rich data containers, just extended by the strongly typed properties. It is much better if you create a separate model for each view and connect this model to the generated class using, for example, AutoMapper. Then, you will be able to pass only the required data to your views.

Please let us know your thoughts about this feature in the comments bellow. We appreciate all your feedback.

What's your experience with MVC

We would like to use this oportunity and ask you a few questions about MVC.

Do you have any experience with MVC projects:




Do you use MVC with Kentico:


Are you planning to use MVC in your future projects:




Share this article on   LinkedIn

Radek Pribyl

Hi, I am a technical leader of one the development teams here at Kentico. We are responsible for the portal engine and MVC support.

Comments

Radek Pribyl commented on

Hi Simon,
it is possible to generate these classes only through API.

You can create a console application for this purpose
(follow the documentation: https://docs.kentico.com/display/K9/Using+the+Kentico+API+externally)
and for the classes generation you can get an inspiration from this file:
CMS\CMSAdminControls\UI\Development\Generators\DocumentsCodeGenerator.ascx.cs.
- see the line: ContentItemCodeFileGenerator.Internal.GenerateFiles(...).

Simon commented on

I would like to make a gulp task to re-generate these classes. Is there a way to do this from the command line or through an API?

Radek Pribyl commented on

Hi Kamran,
Yes, your example is correct and can be used for initialization of the object from data row.

Kamran commented on

Hi,

Is the following example of a partial class correct, if we are initializing from a data row.

public partial class PageType
{
public PageType(DataRow dataRow, TreeProvider treeProvider)
: base(CLASS_NAME)
{
base.Initialize(ClassName, dataRow, treeProvider);
}
}