The new DBProviderFactory class lives in the System.Data.Common namespace. Within this Namespace you will see the usual suspects such as DbConnection, DbDataAdapter, DbCommand etc., but note how they are all prefixed with Db. Each of these classes are abstract classes and implement their respective interfaces in the System.Data Namespace. For example, the DbConnection class implements the IDbConnection interface, the DbDataAdapter implements the IDbDataAdapter interface and so on.
Another interesting point to note is that the concrete classes for each provider inherit their respective base classes in the System.Data.Common namespace. For example, the System.Data.OleDb.OleDbConnection class inherits the DbConnection class from the System.Data.Common namespace. The same is true for the System.Data.SqlClient.SqlConnection class and all other provider classes that are installed on your machine.
The job of the DbProviderFactory class is to return concrete classes based on the provider you wish to target. However, each provider has its own implementation of the DbProviderFactory class, so you first need a method of retrieving the correct provider's implementation of the DbProviderFactory class. This is where the DbProviderFactories class comes in.
The DbProviderFactories class, like those above, lives in the System.Data.Common namespace and doesn't really do an awful lot. However, it is responsible for creating concrete DbProviderFactory classes based on the provider you are targeting. For example, if you wanted to target a Microsoft Access database then before you could use any of the concrete OleDb classes you first need an OleDbFactory. The DbProviderFactories class has a method called GetFactory which accepts either an invariant name (i.e. System.Data.OleDb) or a DataRow.
Now, you may be wondering why a DataRow (I know I did), this is because the DbProviderFactories class has another method called GetFactoryClasses that will return a DataTable containing information regarding all of the providers that are installed on your machine. The GetFactory method knows what the structure of this DataTable is and is therefore able to take a DataRow containing the InvariantName and other information and return a concrete implementation of the provider's DbProviderFactory.
In the next section, we will explore the DbProviderFactories in a little more detail and see how we can retrieve a list of all installed providers and retrieve a concrete DbProviderFactory using the GetFactories and GetFactory methods respectively.