turdus-merula
turdus-merula

Reputation: 8854

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?

Upvotes: 0

Views: 4327

Answers (3)

Old Fox
Old Fox

Reputation: 8725

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.

Upvotes: 1

NightOwl888
NightOwl888

Reputation: 56859

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.

Upvotes: 1

chris.w.mclean
chris.w.mclean

Reputation: 1821

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.

Upvotes: 0

Related Questions