BimlScript Code Nuggets
What a Code Nugget Does
In BimlScript, a code nugget embeds a piece of C# or VB inside a Biml (XML) document. The Biml engine evaluates each nugget at compile time and uses the result to replace variables, repeat fragments, or branch on conditions. Code nuggets are what turn a static Biml file into a metadata driven generator for SSIS packages, SSAS cubes, tables, and other BI artifacts.
There are five kinds of code nugget:
- Text nuggets
- Control nuggets
- Class nuggets
- Comments
- Directives
The five look almost the same on the surface. The opening marker is what tells the compiler which kind a given nugget is.
Text Nuggets
A text nugget evaluates the expression it contains and replaces itself with the string form of the result. Text nuggets are the workhorse for switching out names of packages, tasks, components, source tables, and destination tables in a generated SSIS package.
Text nuggets open with '<#=' and close with '#>'. The equals sign at the start is what marks the nugget as a text nugget. There is no equals sign at the end.
The expression inside a text nugget can return any data type. The engine calls 'ToString' on the result before substituting it into the output. The expression can be a single token, a method call, or a chain of operations as long as the whole thing reduces to one value. Text nuggets can run on a single line or span multiple lines.
A small template that builds one truncate and reload package shows the pattern in context:
<#@ template language="C#" tier="1" #>
<#
var packageName = "StageCustomerLoad";
var destinationSchema = "stg";
var destinationTable = "Customer";
#>
<Biml xmlns="http://schemas.varigence.com/biml.xsd">
<Connections>
<OleDbConnection Name="WarehouseConn"
ConnectionString="Provider=SQLNCLI11;Data Source=DwServer;Initial Catalog=WarehouseDb;Integrated Security=SSPI;" />
</Connections>
<Packages>
<Package Name="<#=packageName#>" ConstraintMode="Linear">
<Tasks>
<ExecuteSQL Name="SQL Truncate Stage_<#=destinationTable#>"
ConnectionName="WarehouseConn">
<DirectInput>
TRUNCATE TABLE [<#=destinationSchema.ToUpper()#>].[<#=destinationTable.ToUpper()#>];
</DirectInput>
</ExecuteSQL>
<Dataflow Name="DFT Stage_<#=destinationTable#>">
<!-- transformations -->
</Dataflow>
</Tasks>
</Package>
</Packages>
</Biml>
Three patterns are visible here:
- A text nugget can stand on its own. '<#=packageName#>' substitutes the variable's value into the package name attribute.
- A text nugget can sit next to literal text. The dataflow name 'DFT Stage_<#=destinationTable#>' produces a name that follows a fixed prefix convention with the destination table appended.
- A text nugget can call any expression in scope. '<#=destinationSchema.ToUpper()#>' invokes a method on the variable and substitutes the uppercase result.
Wrapping the substitution in a method like 'ToUpper' is one way to enforce naming conventions inside the generated artifacts without having to remember to apply the convention manually for every package.
What the Other Four Are For
Text nuggets handle substitution. The other four kinds of nugget cover the rest of what BimlScript can do:
- Control nuggets ('<# ... #>') run statements that decide which Biml fragments are emitted: loops, conditionals, variable setup, and external data lookups.
- Class nuggets ('<#+ ... #>') add methods, properties, and fields to the auto generated class that holds the template, so several nuggets can share the same helper.
- Comment nuggets ('<#-- ... --#>') hide content from the compiler so notes can sit inside the template without affecting the output.
- Directive nuggets ('<#@ ... #>') configure the template itself: which language to use, which other files to include, which namespaces to import, and which tier the file runs in.
Each of these is worth its own walkthrough. The text nugget is the simplest and the one used most often, so it is the natural first stop.