How to write a DB-agnostic .NET Core app?

739 Views Asked by At

I'm struggling to port a console app from .NET Framework 4.6.2 to .NET Core 2.0. The app needs to connect to a database whose platform is not known at compile time. In the full framework this was easily achieved by using the DbProviderFactories mechanism which does not exist anymore in .NET Core 2.0.

First, I thought I could simply load the corresponding DbProviderFactory dynamically myself, using code similar to:

public static DbProviderFactory GetFactory(string providerInvariantName)
{
    Type type = Type.GetType(dbProvider.Type);
    if (null != type)
    {
        FieldInfo field = type.GetField("Instance", BindingFlags.DeclaredOnly | BindingFlags.Static | BindingFlags.Public);
        if (null != field && field.FieldType.IsSubclassOf(typeof(DbProviderFactory)))
        {
            object value = field.GetValue(null);
            if (value != null)
            {
                return (DbProviderFactory)value;
            }
        }
    }
}

as done in this library here. And this code works well as long as the assembly containing the DbProviderFactory is referenced at compile time (which kind of defeats the purpose of dynamic loading).

I tried to just drop System.Data.SqlClient.dll into the app's folder, but then the Instance field is null because this seems to be only a stub implementation of the different runtimes assemblies. When referenced statically, the compiler spits out a verbose .deps.json file that points to those. Here's just minor an outtake to give an impression:

...
"runtime.win-x64.runtime.native.System.Data.SqlClient.sni/4.4.0": {
  "type": "package",
  "serviceable": true,
  "sha512": "sha512-38ugOfkYJqJoX9g6EYRlZB5U2ZJH51UP8ptxZgdpS07FgOEToV+lS11ouNK2PM12Pr6X/PpT5jK82G3DwH/SxQ==",
  "path": "runtime.win-x64.runtime.native.system.data.sqlclient.sni/4.4.0",
  "hashPath": "runtime.win-x64.runtime.native.system.data.sqlclient.sni.4.4.0.nupkg.sha512"
},
"runtime.win-x86.runtime.native.System.Data.SqlClient.sni/4.4.0": {
  "type": "package",
  "serviceable": true,
  "sha512": "sha512-YhEdSQUsTx+C8m8Bw7ar5/VesXvCFMItyZF7G1AUY+OM0VPZUOeAVpJ4Wl6fydBGUYZxojTDR3I6Bj/+BPkJNA==",
  "path": "runtime.win-x86.runtime.native.system.data.sqlclient.sni/4.4.0",
  "hashPath": "runtime.win-x86.runtime.native.system.data.sqlclient.sni.4.4.0.nupkg.sha512"
},
...

This is not something that someone can enter manually.

So what would then be a good way to develop a DB-agnostic app in .NET Core?

0

There are 0 best solutions below