Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I dynamically reference an assembly that looks for another assembly?

Apologies for the dodgy question - happy to rephrase if someone has a better suggestion.

I'm trying to create an object by dynamically invoking an assembly belonging to another application.

The following PowerShell code is working nicely for me:

[Reflection.Assembly]::LoadFrom("C:\Program Files\Vendor\Product\ProductAPI.dll")
$bobject = new-object ProductAPI.BasicObject    
$bobject.AddName("Some Name") 

I'm struggling to do the same thing in C#. Based on other posts on StackOverflow I currently have this:

System.Reflection.Assembly myDllAssembly =
System.Reflection.Assembly.LoadFile("C:\\Program Files\\Vendor\\Product\\ProductAPI.dll");

System.Type BasicObjectType = myDllAssembly.GetType("ProductAPI.BasicObject");

var basicObjectInstance = Activator.CreateInstance(BasicObjectType);

The final line results in a TargetInvocationException.

{"Could not load file or assembly 'AnotherObject, Version=1.2.345.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified."

It appears that the BasicObject constructor is trying to invoke AnotherObject (from AnotherObject.dll in the same folder) but can't find it.

Any tips on how to get around this?

like image 998
gf131072 Avatar asked Sep 22 '13 10:09

gf131072


People also ask

What is an assembly DLL?

An assembly is a collection of one or more files and one of them DLL or EXE. DLL contains library code to be used by any program running on Windows. A DLL may contain either structured or object oriented libraries. A DLL file can have a nearly infinite possible entry points.

Is using assembly load a static reference or dynamic reference?

Assembly. Load is a dynamic reference since you're dynamically loading an external DLL at run-time. You would consider a static reference more like when you're adding a reference to a . NET project and building the project with that reference in place.

What is assembly c#?

C# Assembly is a standard library developed for . NET. Common Language Runtime, CLR, MSIL, Microsoft Intermediate Language, Just In Time Compilers, JIT, Framework Class Library, FCL, Common Language Specification, CLS, Common Type System, CTS, Garbage Collector, GC.


1 Answers

If it can't find a dependent assembly in the usual places, you'll need to manually specify how to find them.

The two easiest ways I'm aware of for doing this:

  1. manually load the dependent assemblies in advance with Assembly.Load.

  2. handle the AssemblyResolve event for the domain which is loading the assembly with additional assembly dependencies.

Both essentially require you to know the dependencies for the assembly you're trying to load in advance but I don't think that's such a big ask.

If you go with the first option, it would also be worthwhile looking into the difference between a full Load and a reflection-only Load.

If you would rather go with 2 (which I'd recommend), you can try something like this which has the added benefit of working with nested dependency chains (eg MyLib.dll references LocalStorage.dll references Raven.Client.dll references NewtonSoft.Json.dll) and will additionally give you information about what dependencies it can't find:

AppDomain.CurrentDomain.AssemblyResolve += (sender,args) => {

    // Change this to wherever the additional dependencies are located    
    var dllPath = @"C:\Program Files\Vendor\Product\lib";

    var assemblyPath = Path.Combine(dllPath,args.Name.Split(',').First() + ".dll");

    if(!File.Exists(assemblyPath))
       throw new ReflectionTypeLoadException(new[] {args.GetType()},
           new[] {new FileNotFoundException(assemblyPath) });

    return Assembly.LoadFrom(assemblyPath);
};
like image 156
nathanchere Avatar answered Oct 03 '22 14:10

nathanchere