XML Input to custom templates

Posts   
 
    
Posts: 56
Joined: 08-Jun-2010
# Posted on: 08-Jun-2010 17:46:29   

Hello

I'm using llblgen v3 demo.

I want to write my own templates for DTO and Mapping classes . However I do not want some control over which fields are exposed through a DTO and which entities we generate DTO's for. My Plan is to express this in an xml and have my template read in the xml file along with the Abstract Entity Definition.

i've spent the last couple of hours trying to find an example of this in the standard templates with no luck. I also havn't been able to find any documentation on developing custom templates.

So:

  1. Is it possible to use XML files as an input into a template?

  2. is there any template development documentation anywhere?

Thanks for your help ~Brett

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39767
Joined: 17-Aug-2003
# Posted on: 08-Jun-2010 18:08:33   

BrettBailey wrote:

Hello

I'm using llblgen v3 demo.

I want to write my own templates for DTO and Mapping classes . However I do not want some control over which fields are exposed through a DTO and which entities we generate DTO's for. My Plan is to express this in an xml and have my template read in the xml file along with the Abstract Entity Definition.

i've spent the last couple of hours trying to find an example of this in the standard templates with no luck. I also havn't been able to find any documentation on developing custom templates.

So:

  1. Is it possible to use XML files as an input into a template?

Yes, if you use .lpt templates (the template form in which the Nhibernate, linq to sql and EF templates are written in).

You can just open the file using a normal XML reader. To include an assembly reference, add: <$ full path + filename of assembly $>

example: <$ c:\program files\Solutions Design\LLBLGen Pro\RuntimeLibraries\DotNet11\SD.LLBLGen.Pro.ORMSupportClasses.dll $>

or if you reference a .net framework assembly you can of course just specify the dll without the path.

namespace include: Syntaxis: <[ namespace name ]> Example: <[ System.Data.SqlClient ]>

What you can also do is: The fields you don't want to show up, go to the entity in the designer and to the code generation info tab, and select the field, then add a custom property for that field, whatever you want, and in the lpt template you can write code which obtains the CustomProperties (which is a hashtable with string name/value pairs) from the field element and verify whether your special value is present. If so, skip the field in your loop.

  1. is there any template development documentation anywhere?

The SDK docs are currently being written. We hope to have a beta form of these at the end of the week.

Frans Bouma | Lead developer LLBLGen Pro
Posts: 56
Joined: 08-Jun-2010
# Posted on: 08-Jun-2010 18:41:17   

Thanks Otis that was really helpful!
The CustomProperty approach is very interesting. I can see where to set them in the llblgen designer but I don’t quite follow how to read them from the template. Can you point me at or post an example?

Are Custom Properties accessible from “.template “ template files? Can you mix .templates with .lpts ?

Thanks ~Brett

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 09-Jun-2010 05:44:51   

Frans was talking about .lpt templates. I recommend you to download the ASP GUI Templates to see how .lpt and Custom Properties work together. That would be a good beginning.

David Elizondo | LLBLGen Support Team
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39767
Joined: 17-Aug-2003
# Posted on: 09-Jun-2010 09:50:28   

daelmo wrote:

Frans was talking about .lpt templates. I recommend you to download the ASP GUI Templates to see how .lpt and Custom Properties work together. That would be a good beginning.

Those aren't available on the main website (yet) wink .

I'll try to write up a small tutorial for you today.

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39767
Joined: 17-Aug-2003
# Posted on: 09-Jun-2010 16:59:58   

The easiest way to do what you want is through a 3rd option I haven't mentioned yet: frameworksettings files. (this is documented in the upcoming SDK docs btw)

Create a .frameworksettings file, e.g. mysettings.frameworksettings, and place it in the folder you specify as 'AdditionalTemplatesFolder' in Project properties of your project.

The format is as follows:

<?xml version="1.0" ?>
<frameworkSettings xmlns="http://sd/llblgen/pro/frameworkSettingsDefinition.xsd">
    <supportedFrameworks>
        <framework name=""/>
        <!-- more -->
    </supportedFrameworks>
    <settingDefinitions>
        <settingDefinition name="" description="" type="" category="" targetElement="" 
            default="" source="" defaultSource=""/>
        <!-- more -->
    </settingDefinitions>
    <valueLists>
        <valueList name="">
            <value valueText=""/>
            <!-- more -->
        </valueList>
        <!-- more -->
    </valueLists>
</frameworkSettings>
<!-- more-->

suggests of course you can specify more than one of the element it is placed below.

If you're generating for the LLBLGen Pro runtime framework, specify for 'name' in the <framework> element: "LLBLGen Pro Runtime Framework"

It's now time to define some settings. The easiest way to edit settings is to use settings which are 'defaults' and refer to them in an element specific setting.

Target types To specify which element the setting is defined for (which also means: in which editor the setting is showing up), a target element type has to be specified, which is a numeric value. You can add multiple values together to specify that a setting is meant for multiple elements.

Project: 1 Entity: 2 ValueType: 4 TypedList: 8 TypedView: 16 SPCall: 32 Normal field: 64 reserved: 128 Navigator returning single value: 256 Navigator returning collection: 512 TypedList field: 1024 TypedView field: 2048 SPCall parameter: 4096 Field mapped onto related field (forf): 8192

Defaults are always specified at the project level.

  • settingDefinition attribute definitions:
  • name. The name of the setting. Has to be unique. This is also used for the name of the surrogate property which is edited in the propertygrid description. The description text which is shown in the pane below the property grid
  • type. This is the type of the surrogate property. Values can be bool, int, string, enum category. This is the category under which the setting is stored. Used by the property grid.
  • targetElement. This is a numeric enum value for the target element the setting is for.
  • default. This is the default value of the setting. It has to be convertible from string to type. Optional, unless canBeEmpty is set to false, in which case Default is required.
  • source. This is the name of the source for the values of the setting. If type is a string, this is the name of a list of string values defined as a valuelist, if type is an enum, it's the full name of the enum type (including assembly name). This name is used with the System.Type class to load the enum type. Optional.
  • defaultSource. This is the name of a default setting which is used to obtain the default value from. If specified, it overrules default. The name specified has to be the name of a setting which has TargetElement set to 1 (project). Optional.
  • canBeEmpty. This is a boolean flag which signals if a setting can be the empty string. Only necessary for string typed setting definitions. Default is true. If canBeEmpty is set to false, and an empty string is specified, the value is changed to null, which will revert to the default value. It's required that when canBeEmpty is set to false, default is set to a valid value.

So to specify if an entity has to be used for a dto, you can define the following default: <settingDefinition name="GenerateDTOClassDefault" targetElement="1" description="This setting specifies the default for the setting whether a DTO class has to be generated for the entity. Default is true" category="Defaults" type="bool" default="true" canBeEmpty="false"/>

(in the frameworksettings file of yours of course)

This setting is available in the Project properties, 'output setting values' tab. To overrule this per entity, we define a second setting: This has as target element '2' which is 'entity': <settingDefinition name="GenerateDTOClass" targetElement="2" description="This setting specifies whether a DTO class has to be generated for the entity. Default is true." category="General" defaultSource="GenerateDTOClassDefault" type="bool" default="true" canBeEmpty="false"/>

This setting will show up in the code gen. info tab of an entity's editor. You can there overrule the setting you defined in the project properties' output settings tab, which contains the default.

You can repeat this for a 'NormalField' (target element value 64).

In your code, you can read the setting value as follows: on the object, read the OutputSettingValues property, which returns the OutputSettingValuesContainer object. that object has a couple of methods (see the core assembly reference manual), e.g. GetRealBoolSettingsValue(name, project).

so to read the setting value 'GenerateDTOClass' for the current entity, do: bool generateDTOClass = currentEntity.OutputSettingValues.GetRealBoolSettingValue("GenerateDTOClass", currentProject);

(where 'currentProject' and 'currentEntity' are variables you set with the proper element)

We hope to have the docs available at the end of the week, so till then you have to use trial/error and check the shipped .lpt templates for linq to sql, nhibernate and entity framework to see how it's done there.

Frans Bouma | Lead developer LLBLGen Pro