tags:

views:

27

answers:

2

Hi!

I'm writing an interface that will be implemented by a lot of classes, and I'm writing a class that will hold a collection of instances of these implementations. Every class will have a default constructor.

So, is there a simple way (e.g. using some kind of reflection) to put an instance of each of these implementing classes to the collection? Besides doing it manually, which is simple, yes, but a lot of work and error prone (what if I missed an implementation while writing the method? What if a new implementation came and I forgot to update the given method?).

So, what I would like is to be able to iterate through all classes of a given namespace or maybe through the list of all available classes. My method then would simply check, through reflection, if the given class implements the given interface, and if it does, puts it into the collection.

Thank you.

+2  A: 

You need to call Assembly.GetTypes() to get every class in an assembly, call typeof(IMyInterface).IsAssignableFrom to check for classes that implement the interface, then call Activator.CreateInstanse to instantiate the class.

Using LINQ:

typeof(IMyInterface).Assembly.GetTypes()
                             .Where<Type, bool>(typeof(IMyInterface).IsAssignableFrom)
                             .Select(t => Activator.CreateInstance(typeof(T)))
                             .ToArray()
SLaks
Great, thank you, this works!
dzs
+2  A: 

Here it is without LinQ, spread out so you can see what's going on. But otherwise it's exactly the same as what SLaks wrote.

It get's all classes implementing the interface IFoo.

 List<IFoo> items = new List<IFoo>();

//Iterate through all types
foreach (Type type in Assembly.GetExecutingAssembly.GetTypes) {

    //Check the type is public and not abstract
    if (!type.IsPublic | type.IsAbstract)
        continue;

    //Check if it implements the interface IFoo
    if (typeof(IFoo).IsAssignableFrom(type)) {

        //Create an instance of the class
        //If the constructor has arguments put them after "type" like so: 
        //Activator.CreateInstance(type, arg1, arg2, arg3, etc...)
        IFoo foo = (IFoo)Activator.CreateInstance(type);

        //Add the instance to your collection
        items.Add(foo);

    }
}
Homeliss
Thanks for the more explanatory code. And, besides, it looks to be a good idea to check if the class is not abstract.
dzs