Skip to content

API for Code based configuration for DBProviderFactories #16532

@kkurni

Description

@kkurni

Problem

DbProviderFactories in .NET Framework provides an API to manage DbProviderFactory which configured in machine.config and load that assembly from GAC via reflection

In Corefx, there is no more GAC and machine.config.

Community are asking to have a standard way to manage DbProviderFactory to write provider agnostic code in libraries.
https://github.com/dotnet/corefx/issues/4571
https://github.com/dotnet/corefx/issues/5782

https://msdn.microsoft.com/en-us/library/ms971499.aspx

Proposal

We will bring back DbProviderFactories in CoreFx.
But instead of register/read the configuration from machine.config, we will provide a code based configuration.

This will allow application writer to hook this with any configuration mechanism.

Contract Changes

We will bring back DbProviderFactories.GetFactory functions in V1 contract which will support .Net 4.6.2.
And add "RegisterFactory" functions in V2 contract to support .Net vNext. (version after 4.6.2)

For portability, we will bring "RegisterFactory" into .Net vNext and should work side by side with file config behavior. e.g code based config will override file based config).

Portable library (such as ORM), can start using GetFactory and target it for .Net 4.6.2.
If this library used in .NET 4.6.2 , GetFactory will return factory which defined in machine/app configs.
Corefx application which used this portable library can register their factory using "RegisterFactory".

Once we release "RegisterFactory" into .Net vNext, The behavior will be work seamless in both frameworks.

namespace System.Data.Common
{
    public static class DbProviderFactories
    {
        // V1 -- Supported by .NET Framework 4.6.2 (the upcoming version)
        public static DbProviderFactory GetFactory(string providerInvariantName);
        public static DbProviderFactory GetFactory(DbConnection connection);

        // V2 -- Supported by .NET Core 1.0 and by .NET Framework vNext (version after 4.6.2)
        public static void RegisterFactory(string providerInvariantName, DbProviderFactory factory);
        public static IEnumerable<string> GetFactoryProviderNames();
    }
}

DbProviderFactories

CoreFx Implementation

public abstract class DbProviderFactories
    {

        internal static readonly Dictionary<string, Func<DbProviderFactory>> _configs = new Dictionary<string, Func<DbProviderFactory>>();

        public static DbProviderFactory GetFactory(string providerInvariantName)
        {
            ADP.CheckArgumentLength(providerInvariantName, nameof(providerInvariantName));

            if (_configs.ContainsKey(providerInvariantName))
            {
                return _configs[providerInvariantName]();
            }

            throw ADP.ConfigProviderNotFound();
        }

        public static DbProviderFactory GetFactory(DbConnection connection)
        {
            ADP.CheckArgumentNull(connection, nameof(connection));
            return connection.ProviderFactory;
        }

        public static void RegisterFactory(string providerInvariantName, DbProviderFactory factory) {
            ADP.CheckArgumentNull(providerInvariantName, nameof(providerInvariantName));
            ADP.CheckArgumentNull(constructorDelegate, nameof(constructorDelegate));

            _configs[providerInvariantName]  = factory;
        }

        public static IEnumerable<string> GetFactoryProviderNames() {
             return _configs.Keys.toArray();
        }
    }

Usage

For CoreFX application, You need to register your provider factory during startup of your application.

public static void Startup()
        {
            //SqlClientFactory is a singleton factory
            DbProviderFactories.Add("System.Data.SqlClient", SqlClientFactory.Instance);

            //You can use other factory which not singleton.
            DbProviderFactories.Add("System.Data.OtherProvider", new OtherProviderFactory());
        }

Progress

I have created initial commit on my branch to inspect what are the changes needed.
kkurni/corefx@68380b3

Metadata

Metadata

Assignees

Labels

api-needs-workAPI needs work before it is approved, it is NOT ready for implementationarea-System.Data

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions