简体   繁体   中英

Why does Activator.CreateInstance() fail in dynamically loaded assembly?

Suppose I have a Host / Plugin scenario:

Host:

static void Main(string[] args)
{
    var path = @"D:\Plugin.dll";
    var assembly = Assembly.LoadFile(path);
    var type = assembly.GetType("Plugin.K");
    var method = type.GetMethod("Run");
    var instance = Activator.CreateInstance(type);

    method.Invoke(instance, new object[] {});
}

Plugin:

public class K {
    public void Run() {
        // EXCEPTION THROWN HERE:
        var x = Activator.CreateInstance("Plugin", "Plugin.K");
    }
}

Then why is the following exception thrown?

An exception of type 'System.IO.FileNotFoundException' occurred in mscorlib.dll but was not handled in user code

Additional information: Could not load file or assembly 'Plugin' or one of its dependencies. The system cannot find the file specified.

Isn't the assembly already loaded in the AppDomain ?

Per MSDN :

The LoadFrom method of the Assembly class loads an assembly given its file location. Loading assemblies with this method uses a different load context.

The recommended way is to use the static (Shared in Visual Basic) Load method of the System.Reflection.Assembly class.

See the above link for additional options.

The assembly is already loaded by the appdomain.

after I looked over the source code of Activator.CreateInstance I found a solution for you:

public class K
{


    public void Run()
    {

        //var f1 = Assembly.GetAssembly(typeof (K)).CreateInstance("Plugin.K");
        //var f2 = Assembly.GetExecutingAssembly().CreateInstance("Plugin.K");
        //var f3 = Activator.CreateInstance(typeof(K));

        //won't throw exception
        var x = Activator.CreateInstance(null, "Plugin.K");

    }
}

the problem was inside the activator.createinstance, when the activator tried to load the assembly name and then the assembly.

when you pass null as assembly name the activator will use:

  assembly = RuntimeAssembly.GetExecutingAssembly(ref stackMark);

note: examples f1-3 also work.

To debug this turn on Fusion logging in .net

How to enable assembly bind failure logging (Fusion) in .NET

If it is a failure to find a dependency then that will be present in the logs.

If not, it will give you more detailed info on why the exception is being thrown.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM