I have a web application that comprises the following:
To keep it safe from anything in the auto generated code, override the connection info in the OnCreated() method of the data context:
using System.Configuration;
namespace MyApplication
{
partial void OnCreated()
{
// attempt to use named connection string from the calling config file
var conn = ConfigurationManager.ConnectionStrings["MyConnectionString"];
if (conn != null) Connection.ConnectionString = conn.ConnectionString;
}
}
This way the dbml designer can do connection stuff its way (which isn't nice outside of a web project), but you grab final control of the connection when the application runs.
How about defining a ConnectionFactory object, that takes an enum as a parameter and returns a fully-formed connection object?
In a perfect world, I think you would refactor you data layer to pick up configuration settings via System.Configuration or relevant constructors/factories. Meaning, you either need to rewire its implicit configuration source, or explicitly set connections from its host/consumer. Another related pattern for centralizing these types of constants is to throw an readonly property into a static helper class and have that class manage the actual resolution from configs, etc.
One place you can look that I think shows good examples of how to do this elegantly is NHibernate and its configuration/mappings management. Granted, it's a bit of xml hell, and Fluent NHib is more sugary, but most of the real world samples will show you how to reconcile configuration from a supporting assembly vs. the executing assembly.
The configuration file for the startup project will define the configuration settings for all included projects. For example if your web project is the startup project, any reference to "appSettings" will look for settings from web.config, this includes any references to "appSettings" from your data access project. So copy any config settings from the Data Access project's app.config to the web project's web.config.
Here's one way to look at it. Which component should make the decision about which database to use? It's possible that the database (or at least the connection string) could change in the future. Does the website decide which database to use? Or, does the DAL decide?
If you have dev, QA, UAT and prod databases, managing these connection strings is crucial.
If the website decides, it should pass the connection string from its web.config to the DAL. If the website isn't supposed to know or care where the data comes from, then the connection string belongs in the DAL.
Thanks for the responses.
Those of you who say the app will use the setting in the web.config are correct for instances where I reference it in my own code:
_connectionString = ConfigurationManager.AppSettings["ConnectionString"];
..but there is a different issue with LINQ-SQL datacontexts - I think they include connections strings in the compiled dll for use in the parameterless constructor. As tvanofosson says, I need to create datacontexts by passing in a reference to the connection string in the web.config. Which is where I was getting into a tangle :)