0

Is there anyway to invoke methods using C# Reflection with embedded/reference dlls?

For example consider the following senario. I have a assembly call User.dll, which have the class as bellow

namespace User
{
    public class UserInfo
    {
        public static string Name = "Username";
    }
}

Using the above dll as reference, I can able to compile the following code and access UserInfo.Name variable.

using User;
using System.Windows.Forms;

public class Test
{
    public Test()
    {
        MessageBox.Show("Name : " + UserInfo.Name);
    }
}

Consider the above code is in another dll called Test.dll assembly. Using Assembly.LoadFile("Test.dll") and C# Reflection, when I try to invoke the Constructor, getting File not found runtime error.

Error

System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.IO.FileNotFoundException: Could not load file or assembly 'DynamicAssembly, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified. at Test..ctor() --- End of inner exception stack trace --- at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor) at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) at System.Reflection.ConstructorInfo.Invoke(Object[] parameters)

Muhammed Shevil KP
  • 1,404
  • 1
  • 16
  • 21
Ramanan
  • 159
  • 1
  • 11

2 Answers2

0

Assembly.LoadFile method only loads the specified file. You need to use Assembly.LoadFrom method in your case. Please check for differences between Assembly.LoadFile and Assembly.LoadFrom

LoadFrom() goes through Fusion and can be redirected to another assembly at a different path but with that same identity if one is already loaded in the LoadFrom context.

LoadFile() doesn't bind through Fusion at all - the loader just goes ahead and loads exactly* what the caller requested. It doesn't use either the Load or the LoadFrom context.

Your executing code sample would be like

    static void Main(string[] args)
    {
        var fileName = ""; //put here test.dll path
        Assembly ass = Assembly.LoadFrom(fileName);

        var type = ass.GetType("Test.Test"); 

        var test = Activator.CreateInstance(type);
    }
Community
  • 1
  • 1
Mutlu Kaya
  • 129
  • 7
  • Thanks @nmkaya. I tried with LoadFrom method too. But the issue is, if the referencing assembly (User.dll) is in different path its not invoke the method and getting the same FileNotFound exception. So the only work around found that, **programmatically copy or moving the reference assemblies (eg. User.dll) to executable application directory** before invoking the method. (eg. Debug\bin). – Ramanan Dec 19 '17 at 07:25
  • @ramanan.java, User.dll should be in Test.dll's location or Gac, otherwise Test.dll would not work even it's added as project reference (in this case test project assemlies are copied to main app location also). you don't need to copy Test.dll and User.dll if User.dll can be reached from Test.dll' s location. Note that i checked how it works with a test application and i think maybe there is another problem somewhere else in your situation e.g. Main application can not load User.dll because it' s locked by another process. – Mutlu Kaya Dec 19 '17 at 08:33
0

I had the same problem.

I just copied the DLL into bin folder of the project.

Obsidian
  • 3,719
  • 8
  • 17
  • 30