Flush the DbProviderFactories.Get FactoryClasses() cache

The first call to DbProviderFactories.GetFactoryClasses() reads in all classes from machine.config into an internal cache. All subsequent calls then use that cache and do not re-read from machine.config.

In AutoTag, if a connector is not installed, we provide the user a link to the connector. And once installed, a link to re-read the providers so they can continue using AutoTag connecting to the newly installed connector.

For this to work the cache has to be re-read by DbProviderFactories.GetFactoryClasses(). The following code forces a re-read.

/// <summary>
/// Force DbProviderFactories to re-read machine.config on the next call to DbProviderFactories.GetFactoryClasses().
/// </summary>
static public void FlushDbProviderFactoriesCache()
{
  try
    {
    FieldInfo initStateFieldInfo = typeof(DbProviderFactories).GetField("_initState", BindingFlags.Static | BindingFlags.NonPublic);
    if (initStateFieldInfo != null)
      {
        ConnectionState state = ConnectionState.Closed;
        object initState = initStateFieldInfo.GetValue(state);
        if (initState is ConnectionState)
        {
          state = (ConnectionState)initState;
          if (state != ConnectionState.Closed)
            initStateFieldInfo.SetValue(state, ConnectionState.Closed);
          ConfigurationManager.RefreshSection("system.data");
        }
      }
    }
  catch (Exception)
    {
    // nada
    }
  }