Reputation: 1283
I am having trouble instantiating a form in c# whose name i retrieve from a database, i have eliminated namespaces completely just to be sure i am not getting the object name wrong but still every time the code runs, the object returns as null instead of being the appropriate form.
private static Object CreateObjectInstance(string strObjectName)
{
Object obj = null; // Temporary object
try
{
if (strObjectName.LastIndexOf(".") == -1) // If there is no '.' in the object name
strObjectName = Assembly.GetEntryAssembly().GetName().Name + "." + strObjectName;
obj = Assembly.GetEntryAssembly().CreateInstance(strObjectName);
}
catch (Exception ex)
{
clsAdmFunctions.RecordException(ex); // Record error to the database
MessageBox.Show("Error instantiating the object\n\nDescription : "+ex.Message, "Object Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
obj = null;
}
return obj;
}
public static Form CreateForm(string strFormName)
{
return (Form)CreateObjectInstance(strFormName);
}
Upvotes: 2
Views: 710
Reputation: 73183
The problem is with your idea that assembly name is a part of your class name. True you need access to your assembly, but ultimately a class name is just Namespace.Class
name. If you provide your actual namespace along with the class, then it works. Change your method to this, perhaps:
private static T CreateInstance<T>(string fullyQualifiedClassName)
{
try
{
return (T)Activator.CreateInstance(Type.GetType(fullyQualifiedClassName));
}
catch (Exception ex)
{
clsAdmFunctions.RecordException(ex); // Record error to the database
MessageBox.Show("Error instantiating the object\n\nDescription : " + ex.Message, "Object Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return default(T);
}
}
In other words you need the namespace too if you're saving it in the database. Just save class.GetType()
as such or class.GetType().ToString()
after which you will see the namespace too saved. The reason is you can have classes with same name, namespace1.Person
and namespace2.Person
in the same assembly.
If you need to read all the namespaces in an assembly, you can do:
foreach(var type in Assembly.WhateverAssembly().GetTypes())
//print type.Namespace;
You're stuck if you dont know the exact namespace. May be you can assume it to be
var namespace = Assembly.WhateverAssembly().GetTypes()[0].Namespace;
You need to have namespaces for your classes, doing otherwise is against .NET's design. If you really really want to have no namespaces for your Forms, you just need to specify just the class name, exclude the assembly name. Just call:
CreateInstance<MyForm>("MyForm");
provided MyForm
is global
and the assembly is just the same. If forms are in different assembly, then load it first using Assembly.Load
or Assembly.LoadFrom
and then create instance.
Upvotes: 1
Reputation: 8147
Your key method CreateObjectInstance
should work OK so I am guessing it is the parameter being passed in? In my example I've shown how to include full namespace and class name etc:
namespace Example.SubFolder
{
internal class frmAdmAbout
{
public string Name { get; set; }
}
}
namespace Example.ActualApp
{
using System;
using System.Reflection;
internal class Program
{
static void Main(string[] args)
{
var newItem = CreateObjectInstance("Example.SubFolder.frmAdmAbout");
if (newItem == null)
{
Console.WriteLine("Failed to create!");
}
else
{
Console.WriteLine("Successfully created!");
}
Console.ReadKey();
}
private static Object CreateObjectInstance(string strObjectName)
{
Object obj = null;
try
{
if (strObjectName.LastIndexOf(".") == -1)
strObjectName = Assembly.GetEntryAssembly().GetName().Name + "." + strObjectName;
obj = Assembly.GetEntryAssembly().CreateInstance(strObjectName);
}
catch (Exception ex)
{
Console.WriteLine("Error instantiating the object\n\nDescription : " + ex.Message);
obj = null;
}
return obj;
}
}
}
Upvotes: 1