Reputation: 23
The following program works only with the classes which are located within the main project. Would you be so kind to advise or correct the code so that it becomes possible to use the classes from other projects. I added reference of the ClassLibrary1 project to the Example01 project.
The error which I am getting is
Unhandled Exception: System.ArgumentNullException: Value cannot be null.
Parameter name: type
at System.Activator.CreateInstance(Type type, Boolean nonPublic)
at System.Activator.CreateInstance(Type type)
at Example01.Program.InstantiateObject(String assemblyName, String fullName) in c:\Projects\Example01\Example01\Program.cs:line 59
object obj = Activator.CreateInstance(objectToInstantiate);
at Example01.Program.RandomizeList[TClass](Int32 count, String assemblyName) in c:\Projects\Example01\Example01\Program.cs:line 34
randomizedList.Add(
at Example01.Program.Main(String[] args) in c:\Projects\Example01\Example01\Program.cs:line 18
List<Class02> randomizedList03 = RandomizeList<Class02>();
Here is my code with the reference what works and what fails:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using ClassLibrary1.Classes;
namespace Example01
{
class Program
{
static void Main(string[] args)
{
// This works
List<Class01> randomizedList01 = RandomizeList<Class01>();
// This works
List<Test01> randomizedList02 = RandomizeList<Test01>();
// This fails
List<Class02> randomizedList03 = RandomizeList<Class02>();
Console.ReadKey();
}
private static List<TClass> RandomizeList<TClass>(int count = 10, string assemblyName = "")
{
if (assemblyName.Length == 0)
assemblyName = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;
var listOfSubClasses = SubClasses<TClass>();
var randomizedList = new List<TClass>();
var rand = new Random();
count = 10;
for (int i = 0; i < count; i++)
randomizedList.Add(
(TClass)
InstantiateObject(assemblyName,
listOfSubClasses.ElementAt(rand.Next(listOfSubClasses.Count()))
.FullName));
return new List<TClass>(randomizedList as IEnumerable<TClass>);
}
// Enumerate all subclasses for the specified class
public static IEnumerable<Type> SubClasses<TClass>()
{
var subclasses =
(from assembly in AppDomain.CurrentDomain.GetAssemblies()
from type in assembly.GetTypes()
where type.IsSubclassOf(typeof(TClass))
select type).ToList();
return subclasses;
}
private static object InstantiateObject(string assemblyName, string fullName)
{
Assembly аsm = Assembly.Load(assemblyName);
// Get the assembly metadata
Type objectToInstantiate = аsm.GetType(fullName);
// Create object on the fly
object obj = Activator.CreateInstance(objectToInstantiate);
return obj;
}
}
#region Sample Classes
public class Class01
{
public string Name { get; set; }
public int Age { get; set; }
}
public class SubClass0101 : Class01
{
public int Length { get; set; }
}
public class SubClass0102 : Class01
{
public int Length { get; set; }
}
public class SubClass0103 : Class01
{
public int Length { get; set; }
}
#endregion
}
Many thanks in advance!!!
Upvotes: 0
Views: 90
Reputation: 7942
Your problem is this line:
assemblyName = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name
You need to enumerate all the referenced assemblies, not just the current executing assembly, so probably need to use GetReferencedAssemblies()
on the result of GetExecutingAssembly()
as your main project is the executing assembly and your referenced project would be a referenced assembly.
Upvotes: 1