1

I'm using a script component to upsert data to MongoDB. As MongoDB driver is not signed, and thus can't be added to GAC, I using the following method to load it at runtime from the known location where all needed reference DLL are saved:

private const string AssembyPath = @"C:\Users\acme\source\repos\import-members-and-optins\lib";
    
static ScriptMain()

{
    AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
}

private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
    // retrieve just a name of this assembly
    var assemblyName = args.Name.Split(',')[0];
    string fullPath = Path.Combine(AssembyPath, string.Format("{0}.dll", assemblyName));
    try
    {
        return Assembly.LoadFile(fullPath);
    }
    catch (Exception ex)
    {
        throw new Exception($"{fullPath} not found", ex);
    }
}

However, I'm getting the following exception, and I'm not even able to debug it, as it's happening before the task is able to run. It's like the handler is never executed. I have checked and my package is running in x86, so I should be able to debug it, but my handler is never hit. :-(

Package Validation Error Error at Data Flow Task [Upsert Mongo [69]]: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.TypeInitializationException: The type initializer for 'ScriptMain' threw an exception. ---> System.IO.FileNotFoundException: Could not load file or assembly 'MongoDB.Driver, Version=2.14.1.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified. at ScriptMain..cctor()
--- End of inner exception stack trace --- at ScriptMain..ctor() --- End of inner exception stack trace --- at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck)

What I'm missing here?

Hadi
  • 36,233
  • 13
  • 65
  • 124
Oscar
  • 13,594
  • 8
  • 47
  • 75
  • Why are you adding a driver to your project? Drivers are install on the machine and get added to the Device Manager. An application does a lookup in the installed device to get the driver, not the application. – jdweng Jan 31 '22 at 12:11
  • Hi @jdweng I'm just adding a reference to MongoDB database driver, which is a standalone dll – Oscar Jan 31 '22 at 12:37
  • Are you executing client or server code? The connection to database should be in the server code. Client should make a request to the server and the server handles the connection to the database. The standalone dll is probably server code which on the first call uses a connection string to connect to the database. – jdweng Jan 31 '22 at 13:05
  • Hi @jdweng This is an SSIS package running in my local machine used to import data to a MongoDB instance. – Oscar Jan 31 '22 at 13:23
  • The SSIS script runs on the server not on your machine. – jdweng Jan 31 '22 at 14:16

1 Answers1

0

I think that the main issue is caused by initiating variables globally within the class which is called before the assembly resolver is fired.

Try not to initiate any variable within the public class ScriptMain : UserComponent class and mover them into the appropriate methods or int the PreExecute method.

Try changing your code to the following:

static ScriptMain()

{
    AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
}

private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
    string AssembyPath = @"C:\Users\acme\source\repos\import-members-and-optins\lib";
    // retrieve just a name of this assembly
    var assemblyName = args.Name.Split(',')[0];
    string fullPath = Path.Combine(AssembyPath, string.Format("{0}.dll", assemblyName));
    try
    {
        return Assembly.LoadFile(fullPath);
    }
    catch (Exception ex)
    {
        throw new Exception($"{fullPath} not found", ex);
    }
}

Also, make sure that no other variables are initiated globally.

Helpful resources

Hadi
  • 36,233
  • 13
  • 65
  • 124
  • Thanks, still wondering how could I miss this, there was a static filed initialized inline, once I moved it to static constructor right after handler initialization now it works fine. – Oscar Feb 01 '22 at 09:06
  • 1
    @Oscar I faced the same issue previously, and spent lot of time to solve it. It is very tricky. – Hadi Feb 01 '22 at 09:22