Include Files in Biml
Why Avoid Repeating Biml
Generating SSIS packages from Biml already removes a lot of repetition compared to clicking through the designer. The next step is to stop repeating the Biml itself. Common fragments such as variable lists, audit task chains, or boilerplate connection definitions can live in a separate file and be pulled into many parent files. A single edit then updates every project that references the fragment.
There are five common techniques for sharing Biml across projects:
- Include files
- CallBimlScript
- Tiered Biml files
- C# and VB code files
- Transformers (BimlStudio only)
This walkthrough focuses on include files.
How an Include Directive Works
An include file behaves like an automated copy and paste. The compiler reads the include directive in the parent file, copies the contents of the referenced file, and pastes them in place of the directive. Whatever was inside the included file becomes part of the parent file at compile time.
A simple example puts a list of variables into a separate file. The parent package file keeps only the structure:
OrderLoadPackage.biml:
<Packages>
<Package Name="OrderLoadPackage">
<Variables>
<#@ include file="LoadCounters.biml" #>
</Variables>
</Package>
</Packages>
LoadCounters.biml:
<Variable Name="InsertedRows" DataType="Int32">0</Variable>
<Variable Name="UpdatedRows" DataType="Int32">0</Variable>
<Variable Name="UnchangedRows" DataType="Int32">0</Variable>
The directive '<#@ include file="LoadCounters.biml" #>' tells the compiler which file to splice in. The included content has to be valid where it lands. In this example the directive sits inside a 'Variables' element, so the included file may only contain 'Variable' elements. Dropping in a 'Package' element there would produce invalid Biml.
Include files are not limited to the .biml extension. Anything text based works: .biml, .txt, .sql, .cs, and so on. The compiler treats the file as a raw text fragment and inserts it verbatim.
Relative and Absolute Paths
When the included file lives outside the project, the directive accepts either a relative or an absolute path:
<!-- Relative file path -->
<#@ include file="..\SharedFragments\LoadCounters.biml" #>
<!-- Absolute file path -->
<#@ include file="C:\BimlAssets\SharedFragments\LoadCounters.biml" #>
Relative paths keep the project portable across machines. Absolute paths are useful when the same shared library lives on a fixed location that every developer maps the same way.
When Include Files Are the Right Choice
Include files shine when the shared content is essentially static markup that gets dropped into the same kind of slot every time. Lists of variables, blocks of audit tasks, and standard connection sets are good fits. A single change in the shared file flows out to every parent on the next build.
If the shared logic needs to accept parameters, run conditional checks, or return different markup depending on the caller, the next step up is CallBimlScript, which gives the included fragment a way to receive arguments and produce output based on them.