Reputation: 197
Lets say I have some interface that looks like the below
public interface IPerson
{
Person GetPerson(string name);
Person SetPerson(Person p);
}
And my person object has some nested objects and maybe it inherits from a base class.
public class Person : SomeBaseClass
{
public Name fullName {get;set;}
// some other stuff
}
Now lets say all the above gets compiled to an assembly (dll). Is it possible to instantiate the Person Object on the fly using reflection?
void Main()
{
Type type = typeof(IPerson);
var instance = Activator.CreateInstace(t);
// can't access properties of Person from instance.. :(
// I wan't to populate all the properties of the object on the fly
// but can't
}
Basically I want to reference the dll or load the assembly dynamically iterate over all the objects in said assembly, create the objects and populate their properties, and finally do something with those objects and their properties. Is this possible? Seems I only have access to Person.Name when I make a static cast.
var oops = (Person)instance; // now I can access. but I dont want to have to cast!
Upvotes: 0
Views: 4568
Reputation: 18155
From your question it's unclear whether all the objects you want to create implement IPerson
or not. If they do then Joe Enzminger's answer will work great. If they don't all implement IPerson
you're going to have to use more reflection to get the set of properties, figure out the type of each property, then act on that.
var properties = instance.GetType().GetProperties();
foreach(var property in properties)
{
var propertyType = property.PropertyType;
if(propertyType == typeof(string))
{
property.SetValue(instance, "A String");
}
else if(propertyType == typeof(int))
{
property.SetValue(instance, 42);
}
// and so on for the different types
}
Upvotes: 0
Reputation: 4394
In order to create a typed instance, you can use Activator.CreateInstance<T>()
. But you need to pass a concrete type, not an interface. So, it should be
Person instance = Activator.CreateInstance<Person>();
If you still need to be able to use interfaces, you should probably use some DI container to map IPerson
interface to Person
class first (could be done via reflection), and then use container to resolve an instance of IPerson
.
Upvotes: 1
Reputation: 11190
Load the assembly. Once the assembly is loaded, you can do:
foreach(var type in assembly.GetTypes())
{
//if the type implements IPerson, create it:
if(typeof(type).GetInterfaces().Contains(typeof(IPerson))
{
var person = (IPerson)activator.CreateInstance(type);
//now you can invoke IPerson methods on person
}
}
This will create an instance of every type in the assembly that implements IPerson, using the default constructor.
Upvotes: 3