Finally:
I'm making this everytime that the app starts or when I choose another environment with app started:
string newConnectionString = "Data Source=xxx.xxx.xxx.xxx;Initial Catalog= .........."
string connectionStringName = "MyConnectionStringName";
string providerKey = MyProject.Service.ConnectionScope.Current.DataProvider.Name;
string applicationName = System.Threading.Thread.CurrentThread.Name;
if (MyProject.DAL.DataRepository.Connections.ContainsKey(connectionStringName))
{
// I'm changing the environment
MyProject.DAL.DataRepository.Connections.Remove(connectionStringName);
}
// Get the current provider
MyProject.DAL.Bases.NetTiersProvider oldProvider = MyProject.DAL.DataRepository.Providers[providerKey];
// Create a new provider
MyProject.DAL.Bases.NetTiersProvider newProvider = new MyProject.DAL.SqlClient.SqlNetTiersProvider();
// Initialize new provider
NameValueCollection collection = new NameValueCollection();
collection.Add("ProviderInvariantName", ((MyProject.DAL.SqlClient.SqlNetTiersProvider)oldProvider).ProviderInvariantName);
collection.Add("Description", oldProvider.Description);
collection.Add("ConnectionString", newConnectionString);
collection.Add("ConnectionStringName", connectionStringName);
collection.Add("UseStoredProcedure", ((MyProject.DAL.SqlClient.SqlNetTiersProvider)oldProvider).UseStoredProcedure.ToString());
collection.Add("EntityCreationalFactoryType", oldProvider.EntityCreationalFactoryType.ToString());
collection.Add("UseEntityFactory", oldProvider.UseEntityFactory.ToString());
collection.Add("EnableEntityTracking", oldProvider.EnableEntityTracking.ToString());
collection.Add("EnableMethodAuthorization", oldProvider.EnableMethodAuthorization.ToString());
collection.Add("ApplicationName", applicationName);
newProvider.Initialize(providerKey, collection);
// Update all objects in memory
MyProject.DAL.DataRepository.LoadProvider(newProvider, true);
((MyProject.DAL.SqlClient.SqlNetTiersProvider)MyProject.DAL.DataRepository.Providers[providerKey]).ConnectionString = newConnectionString;
MyProject.Service.ConnectionScope.Current.DataProvider = newProvider;
MyProject.Service.ConnectionScope.Current.ConnectionStringKey = connectionStringName;
MyProject.Service.ConnectionScope.Current.DynamicConnectionString = newConnectionString; // Optional
Optionally you can update the app.config file everytime you make the change with this code:
try
{
string m_strFullPath = "";
Assembly asm = Assembly.GetExecutingAssembly();
XmlDocument xmlDoc = new XmlDocument();
FileAttributes originalAttributes;
m_strFullPath = ConfigurationManager.OpenExeConfiguration(asm.Location).FilePath;
xmlDoc.Load(m_strFullPath);
originalAttributes = File.GetAttributes(m_strFullPath);
if ((originalAttributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
{
File.SetAttributes(m_strFullPath, FileAttributes.Normal);
}
XmlNodeList nodeList = xmlDoc.SelectSingleNode("/configuration/connectionStrings").ChildNodes;
foreach (XmlNode xn in nodeList)
{
if (string.IsNullOrEmpty(xn.Name) || xn.Name != "add")
{
continue;
}
XmlElement xe = (XmlElement)xn;
if (xe.GetAttribute("name") == connectionStringName )
{
xe.SetAttribute("connectionString", newConnectionString);
break;
}
}
xmlDoc.Save(m_strFullPath);
File.SetAttributes(m_strFullPath, originalAttributes);
}
catch (System.NullReferenceException NullEx)
{
throw NullEx;
}
catch (Exception ex)
{
throw ex;
}
It is working for me.
I think it would'nt be difficult to add a method somewhere (perhaps in DataRepository) to change the current connection passing the new connection string. I'll create a new Issue at Google Code.
I'm still having a problem with BackgroundWorker. By the moment I've disabled the background work and perhaps I will use a thread.
Thanks jeff.