my situation is the next: I'm working with Visual C# 2010 express developing a Windows Forms Application. When the user logins, dinamically build a menustrip with options loaded from a database table. In that table i save id, option name and Form Name.
So, suppose that in my project i have a Form named Contabilidad, it has Contabilidad.cs that is the main class , so if i wanna create a new form and show it i do this:
Contabilidad frmConta = new Contabilidad();
frmConta.Show();
But in this case, because the menu options are stored in database, in database i only have the string "Contabilidad". So, i want to use C# reflection to create a instance of Contabilidad or any other form only with class name in string format.
First i tried this:
Form frmConta= (Form)Activator.CreateInstance(null, "Contabilidad").Unwrap();
Because i read in a StackOverflow question that if i use null i'm referring to current assembly (my forms are all in the same project), but i get this message:
Could not load type 'Contabilidad' from assembly 'AccountingSA, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.
The class definition is the next:
namespace AccountingSA {
public partial class Contabilidad : Form
{
public Contabilidad()
{
InitializeComponent();
} ...
Also i tried this:
Assembly assembly = Assembly.Load("AccountingSA");
Type t = assembly.GetType("Contabilidad");
Form frmConta = (Form)Activator.CreateInstance(t);
But i get ArgumentNullException with this message:
Value cannot be null. Parameter name: type
Because t variable is null.
What i'm do wrong? Thanks in advance.
Use the fully-qualified name of the type:
Type t = assembly.GetType("AccountingSA.Contabilidad");
From the documentation for Assembly.GetType(string)
:
name Type: System.String
The full name of the type.
[...] The name parameter includes the namespace but not the assembly.
You're trying to use the name of the class without specifying the namespace. This should be fine:
Assembly assembly = Assembly.Load("AccountingSA");
Type t = assembly.GetType("AccountingSA.Contabilidad");
Form frmConta = (Form)Activator.CreateInstance(t);
Every version of GetType
requires the fully-qualified type name; the benefit of using Assembly.GetType
is that at least you don't need to also include the assembly name, but as documented you still need the namespace:
The name parameter includes the namespace but not the assembly.
Note that to diagnose something similar in the future, it would have been worth looking at the value of t
after the second line - it will be null, which is why the third line threw an exception.
You should add the namespace:
assembly.GetType("AccountingSA.Contabilidad");
Try this
Form frmConta= (Form)Activator.CreateInstance(null, "AccountingSA.Contabilidad").Unwrap();
Try specifying your class this way:
ContabilidadNamespace.Contabilidad, ContabilidadAssembly
Its too late in the thread to answer, but the earlier answer, in current .NET framework (4.7), not working (The line Assembly assembly = Assembly.Load("AccountingSA"); always throws FileIOException). Currently, working code is (Use Type directly)
Type t = Type.GetType("AccountingSA.Contabilidad");
Form frmConta = (Form)Activator.CreateInstance(t);
or other way using Assembly is
Assembly assembly = typeof(Form).Assembly;
Type t = assembly.GetType("AccountingSA.Contabilidad");
Form frmConta = (Form)Activator.CreateInstance(t);