14

I am trying to load an assembly at runtime, and I'm unsure as to why I can't create an instance of a type in the assembly using the static Activator.CreateInstance(). It works with Assembly.CreateInstance().

string assemblyFilename = "MyAssembly.dll";
string assemblyName = "MyAssembly";
string typeName = "MyAssembly.MyType";

FileInfo fileInfo = new FileInfo(assemblyFilename);

This works:

var assembly = Assembly.LoadFrom(assemblyFilename);
Form form = (Form)assembly.CreateInstance(typeName);

But this does NOT work:

Assembly.LoadFrom(assemblyFilename);
Form form = (Form)Activator.CreateInstance(assemblyName, typeName).Unwrap();

FileNotFoundException thrown:

Could not load file or assembly 'MyAssembly' or one of its dependencies. The system cannot find the file specified.

EDIT:

In both cases, after the Assembly.LoadFrom() call, I can see that my assembly has been loaded when I look in AppDomain.CurrentDomain.GetAssemblies().

Dave New
  • 38,496
  • 59
  • 215
  • 394
  • 1
    The 2nd version should specify a full assembly name, not just the display name, and uses Assembly.Load() under the hood. Not the same thing as LoadFrom(). Troubleshoot with fuslogvw.exe – Hans Passant Sep 07 '12 at 12:39
  • As in "MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=5dc3e20777fed081"? I get the same error – Dave New Sep 07 '12 at 13:09
  • I have even copied the FullName straight from "MyAssembly" in GetAssemblies() and it still doesn't work. So confused! – Dave New Sep 07 '12 at 13:17
  • 1
    @davenewza One more thing, try hooking into the AssemblyResolve event of AppDomain.Current. It should fire when an assembly is not found, perhaps you can see the full assembly name it is looking for there. Perhaps it cannot find a dependency that your MyAssembly uses. – armen.shimoon Sep 08 '12 at 05:53
  • 1
    @davenewza One other thing Dave, try using the assembly qualified name for the type name, ie: TopNamespace.SubNameSpace.ContainingClass+NestedClass, MyAssembly, Version=1.3.0.0, Culture=neutral, PublicKeyToken=b17a5c561934e089 – armen.shimoon Sep 08 '12 at 11:09

4 Answers4

5

You can adjust your file with his path

var path = Assembly.GetAssembly(MyType.GetType()).Location;
var thisAssembly= Assembly.LoadFrom(path);

var TypeName = "";
Type type = thisAssembly.GetType(TypeName);
object instance = Activator.CreateInstance(type);
Bellash
  • 7,560
  • 6
  • 53
  • 86
Aghilas Yakoub
  • 28,516
  • 5
  • 46
  • 51
  • I need to use Activator.CreateInstance() because I won't always have an instance of the assembly available. – Dave New Sep 07 '12 at 12:01
  • how do I crate a class dinamicaly after loading the assembly. defining all its methods? getting a compile error on the methods since i didnt use Using to load it before? thanks – aleXela Feb 20 '23 at 21:48
4

You have to first load the assembly into your current AppDomain:

AppDomain.CurrentDomain.Load(File.ReadAllBytes(assemblyFileName));

EDIT: Does this work?

Form form = (Form)Activator.CreateInstance(Type.GetType(typeName))
armen.shimoon
  • 6,303
  • 24
  • 32
2

Tried to edit original answer but i got no response from author. So just in case some one needs this, here is the code that worked for me

System.Reflection.Assembly assembly = AppDomain.CurrentDomain.Load(File.ReadAllBytes("DLL_PATH"));  
Form form = (Form)assembly.CreateInstance("FullNameSpace.ClassName");
A Khudairy
  • 1,422
  • 1
  • 15
  • 26
0

A variation of A Khudairy's answer here to allow passing in input parameters to access a specific constructor, plus this variation of his answer resolved a problem which I've had and literally been searching on and off for several weeks now trying to resolve (many kudos to him for sharing the answer).

My problem was I wanted to load a .NET 3.5 dll into a new application which was .NET 4.6, but those old dll's used third party controls which looked to use CAS policy. I'd get an error from the third party controls saying I needed to turn in app.config, if I did that I could load and run the files just fine if they were on my local computer, but if I tried to load them from a network drive, which I need to do, then I got a FileIOPermission error.

Tried running combinations of NetFx40_LegacySecurityPolicy with loadFromRemoteSources and useLegacyV2RuntimeActivationPolicy, and tried several different methods such as Activator.CreateInstance() which usually works for me, tried creating a sandbox (though I don't know if I did it properly), but nothing would work, except for below. Note, my user controls were also based off of a base class. I had run some CAS command prompt commands prior to grant access to the network drive, and my app should be running in full trust. Regardless, it didn't look like any of the methods I had tried other than this one has worked so far for me.

The code fix:

object dllUserControl = null;
System.Reflection.Assembly assembly = AppDomain.CurrentDomain.Load(File.ReadAllBytes("DLL_PATH"));  
dllUserControl = assembly.CreateInstance("FullNameSpace.ClassName",true,BindingFlags.Default,null,constructorParams[],null,null);

... from which I could later cast the object as needed (to my base class) to later launch it in it's own Form/Window.

ZF007
  • 3,708
  • 8
  • 29
  • 48
DeltaPng
  • 505
  • 4
  • 6