How can i tell SubSonic 2 to use a different .config file?
Categories:
Configuring SubSonic 2 to Use a Custom Configuration File

Learn how to direct SubSonic 2.x to load its database connection settings from an alternative .config file, enabling flexible deployment and environment-specific configurations.
SubSonic 2.x, a popular ORM for .NET, typically relies on the standard app.config
or web.config
file for its database connection string. However, in scenarios requiring dynamic environments, multi-tenant applications, or simply better separation of concerns, you might need SubSonic to read its configuration from a different file. This article will guide you through the process of overriding Sub SubSonic's default behavior to specify a custom configuration file.
Understanding SubSonic's Configuration Mechanism
By default, SubSonic 2.x uses the System.Configuration.ConfigurationManager
class to retrieve connection strings. This class is designed to read from the application's primary configuration file (App.config
for desktop apps, Web.config
for web apps). To make SubSonic look elsewhere, we need to intercept or modify how it accesses these settings. The key is to leverage the SubSonic.DataService.Provider
property, which allows us to programmatically define the connection string or even the entire provider.
flowchart TD A[Application Start] --> B{SubSonic Init} B --> C{Default: Read app.config/web.config} C --> D[Use Connection String] B --> E{Custom Config Logic} E --> F[Load Custom .config File] F --> G[Extract Connection String] G --> H[Set SubSonic.DataService.Provider] H --> D
Flowchart illustrating SubSonic's default and custom configuration paths.
Method 1: Programmatically Setting the Connection String
The most straightforward way to tell SubSonic to use a different connection string is to set it directly in your application's startup code. This involves reading your custom configuration file manually and then assigning the connection string to SubSonic.DataService.Provider.DefaultConnectionString
.
using System.Configuration;
using System.IO;
using SubSonic.DataProviders;
public static class SubSonicConfig
{
public static void InitializeSubSonic(string configFilePath)
{
// Load the custom configuration file
ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
fileMap.ExeConfigFilename = configFilePath;
Configuration config = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
// Get the connection string from the custom config
ConnectionStringSettings connectionStringSetting = config.ConnectionStrings.ConnectionStrings["MyCustomConnection"];
if (connectionStringSetting != null)
{
// Set the default connection string for SubSonic
DataService.GetInstance("MyCustomConnection").DefaultConnectionString = connectionStringSetting.ConnectionString;
// Or, if you want to set the global default:
// DataService.DefaultConnectionString = connectionStringSetting.ConnectionString;
// You might also need to set the provider type if it's not the default
// DataService.GetInstance("MyCustomConnection").DefaultProvider = ProviderFactory.GetProvider(connectionStringSetting.ProviderName);
}
else
{
throw new ConfigurationErrorsException($"Connection string 'MyCustomConnection' not found in {configFilePath}");
}
}
}
// Example usage in your application startup (e.g., Global.asax or Program.cs)
// string customConfigFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "CustomSettings.config");
// SubSonicConfig.InitializeSubSonic(customConfigFile);
C# code to load a connection string from a custom configuration file and apply it to SubSonic 2.x.
Ensure your custom configuration file has the correct XML structure for connection strings, similar to a standard app.config
or web.config
file. For example:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<connectionStrings>
<add name="MyCustomConnection" connectionString="Data Source=server;Initial Catalog=database;Integrated Security=True" providerName="System.Data.SqlClient" />
</connectionStrings>
</configuration>
Method 2: Using a Custom SubSonic Provider (Advanced)
For more complex scenarios, you might consider creating a custom IDataProvider
implementation. This allows you to completely control how SubSonic retrieves its settings, including connection strings, and even how it interacts with the database. While more involved, it offers maximum flexibility.
using System.Configuration;
using SubSonic.DataProviders;
using SubSonic.SqlGeneration.Schema;
public class CustomConfigDataProvider : SqlDataProvider
{
public CustomConfigDataProvider(string connectionString, string providerName)
: base(connectionString, providerName)
{
// You can add custom logic here if needed
}
// Override methods if you need to customize behavior beyond just the connection string
// For example, if you want to dynamically change the connection string based on context
// public override string ConnectionString
// {
// get { return GetDynamicConnectionString(); }
// }
}
// To use this:
// In your application startup:
// string customConfigFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "CustomSettings.config");
// ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
// fileMap.ExeConfigFilename = customConfigFile;
// Configuration config = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
// ConnectionStringSettings connectionStringSetting = config.ConnectionStrings.ConnectionStrings["MyCustomConnection"];
// if (connectionStringSetting != null)
// {
// IDataProvider customProvider = new CustomConfigDataProvider(
// connectionStringSetting.ConnectionString,
// connectionStringSetting.ProviderName
// );
// DataService.Set // Note: SubSonic 2.x might require a different approach to register custom providers globally
// // You might need to set it for a specific repository or use DataService.GetInstance("MyCustomConnection").DefaultProvider = customProvider;
// }
Example of a custom SubSonic data provider, offering advanced configuration control.
IDataProvider
is an advanced technique. For most scenarios, programmatically setting the DefaultConnectionString
as shown in Method 1 is sufficient and much simpler to implement.Deployment Considerations
When deploying your application, ensure that your custom configuration file is present in the application's output directory. For web applications, this might mean placing it in the root directory or a specific subfolder. For desktop applications, it should reside alongside the executable. Always consider how you will manage these custom configuration files across different environments (development, staging, production) to avoid manual errors.
1. Create Custom Configuration File
Create a new XML file (e.g., CustomSettings.config
) in your project and ensure its 'Copy to Output Directory' property is set to 'Copy always' or 'Copy if newer'.
2. Add Connection String
Populate CustomSettings.config
with your desired connection string, formatted like a standard connectionStrings
section.
3. Implement Initialization Logic
Add the C# code from Method 1 to your application's startup routine (e.g., Global.asax.cs
for web apps, Program.cs
for console/desktop apps).
4. Call Initialization Method
Invoke your InitializeSubSonic
method with the path to your custom configuration file before any SubSonic data access occurs.
5. Test Thoroughly
Run your application and verify that SubSonic is successfully connecting to the database using the connection string from your custom file.