DbProviderFactories Registration Issue in .NET 9 with C++/CLI Loader DLL

Ryan Wagner 20 Reputation points
2025-04-16T00:12:04.7066667+00:00

Update#2 on April 17 2025

I tried included the system.data.oledb 9.0.4 .nuget package in share.vcxproj and changed share.cpp to "using System.Windows.Forms;

using System.Data.Common;

using System.Data.OleDb;

namespace Share

{

public static class ApplicationDb

{

    static ApplicationDb()

    {

        // IMPORTANT: I really want to use system.data.oledb in the share.dll, but first want to see if it can be loaded in interop.dll..

        // This runs the first time the class is used

        Console.WriteLine("Share - At beginning of ApplicationDb ctor");

        DbProviderFactories.RegisterFactory("System.Data.OleDb", OleDbFactory.Instance);

        const string providerInvariantName = "System.Data.OleDb";

        var factory = DbProviderFactories.GetFactory(providerInvariantName);

        Console.WriteLine("Share - At beginning of ApplicationDb ctor");

    }

    public static void SayHello() => Console.WriteLine("Hello from Share!");

}

}", and after running client.exe I get this error "[Interop] Initializing...

Current Directory: D:\temp\LoadOledbTest\x64\Debug

About to call SayHello()...

EXCEPTION:

System.IO.FileNotFoundException: Could not load file or assembly 'System.Data.OleDb, Version=9.0.0.4, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'. The system cannot find the file specified.

File name: 'System.Data.OleDb, Version=9.0.0.4, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'

at Share.ApplicationDb..cctor()

at Share.ApplicationDb.SayHello()

at InitializeInterop() in D:\temp\LoadOledbTest\Interop\Interop.cpp:line 58

Press Enter to exit...".

Question: Why the error has version "9.0.0.4" when I am using version "9.0.4"?


Update#1 on April 17 2025
I created a very small example program to show that I cannot load system.data.oledb.dll version 9.0.4 or 9.0.2 and get OleDbFactory.Instance and register from interop.dll. I would ultimately like to use the oledb inside share.dll but thought I would try to load it from interop.dll to see if this solves the problem with it not working from share.dll. This example program is just to learn how to do this as I need to be able to do this in a much larger program.

I am sharing the code for this very small example program on my OneDrive via link below.

https://pglibinoutlook-my.sharepoint.com/:u:/g/personal/ryan_nexussi_com/ER1evLiVuNNGraMwK5HmdZgBZ-X7JOvmRGcJirrgfTTzGA?e=fjruG2

I would appreciate it if someone has the time to suggest how to get system.data.oledb.dll to load and register it in either interop.dll or share.dll. Goal is to use it in share.dll.

One more thing. I am building all projects in Debug x64. I am not using AnyCPU. I am also using Visual Studio 2022.

Thanks,


Original Question:

The conversion of C# .NET 4.8 applications to .NET 9-windows is presenting a challenge with the error: "Exception: ArgumentNullException: Value cannot be null. (Parameter 'factory')" when attempting to register the OleDbFactory.

The following context is provided:

The application architecture involves a C++ application that loads a C++/CLI DLL (interop.dll) which in turn loads a .NET 9-windows DLL (share.dll).

The code snippet that fails is DbProviderFactories.RegisterFactory("System.Data.OleDb", OleDbFactory.Instance);, where OleDbFactory.Instance is null.

This issue does not occur when running a separate C# .NET 9-windows executable (tools.exe) that successfully registers the factory.

A ModuleInitializer is utilized in another application to ensure necessary assemblies load, which successfully registers the OleDbFactory.

The specific code being executed is as follows:

public static class ApplicationServices
{
    public static void InitializeOleDb()
    {
        try
        {
            Assembly loadedAssembly = Assembly.Load("System.Data.OleDb");
            if (loadedAssembly != null)
            {
                Console.WriteLine("System.Data.OleDb Assembly loaded.");
            }
            else
            {
                Console.WriteLine("System.Data.OleDb Assembly load failed.");
            }
            try
            {
                DbProviderFactories.RegisterFactory("System.Data.OleDb", OleDbFactory.Instance);
                Console.WriteLine("OleDbFactory registered successfully.");
            }
            catch (Exception factoryEx)
            {
                Console.WriteLine($"OleDbFactory instantiation error: {factoryEx.Message}");
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Error registering OleDb: {ex.Message}");
        }
    }

    static ApplicationServices()
    {
        InitializeOleDb();
    }
}

The question is: What is the best approach to call InitializeOleDb() so that the system.data.oledb.dll registers correctly in share.dll and ensures that OleDbFactory.Instance is not null?

Developer technologies | .NET | .NET CLI
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Ryan Wagner 20 Reputation points
    2025-04-21T17:47:29.25+00:00

    This issue was resolved by a co-worker at my office. Big thanks for his help.

    The problem was that the interop.dll was looking for the "system.data.oledb.dll" in the "D:\temp\LoadOledbTest\x64\Debug\runtimes\win\lib\net9.0" directory which did not exist on my system.

    Thanks, to anyone who worked on this issue.

    Status: This post can be closed now.

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.