[Mono-list] Instantiating all classes from a namespace
    Jonathan Pryor 
    jonpryor at vt.edu
       
    Sun Oct  5 16:26:45 EDT 2008
    
    
  
On Mon, 2008-09-29 at 13:46 -0700, Esdras Beleza wrote:
> I'm programming an application and I want to divide its functionalities into
> modules. I put them into some classes that belong to a namespace
> App.Modules. Each module has a property (an attribute) "Name". 
Fine, though I would suggest looking at Mono.Addins before writing your
own custom module system...
> I want to create a list of all modules dinamically, creating an instance of
> each class in App.Modules (probably using foreach) and doing something like
> System.Console.Writeline(SomeModule.GetName()).
> 
> The question is: how can I iterate inside a namespace classlist, and create
> a new instance of each class of it?
You do NOT, in general, want to rely upon Reflection in this case, for
two reasons:
1. There is no way to get all types from only a specific namespace.
Namespaces "don't exist" in Reflection, they're just part of the name,
so to get all types in a given namespace you have to enumerate *all*
types in the assembly.
2. Enumerating all types in the assembly will create a System.Type
instance for each type, and those types can't be collected by the GC (I
forget why, and this may have changed since I last heard, but this is my
current operating assumption).
Consequently, you shouldn't do this for "normal" "app-ish" things.
Instead, if you don't want to use Mono.Addins I would suggest creating a
new Assembly-level attribute, e.g.:
	[AttributeUsage(AttributeTargets.Assembly)]
	public class ModuleAttribute : Attribute {
		public ModuleAttribute (Type type);
		public Type Type {get;}
	}
Then, for all modules you can allow them to be easily found with:
	[assembly:Module (typeof (YourModuleType))]
Then you can use reflection on the assembly to get all ModuleAttribute
instances and use the ModuleAttribute.Type property to get a Type
instance for Just Those Types (instead of all types in the assembly),
and then you can create instances via Activator.CreateInstance:
	IEnumerable<object> modules = Assembly.GetExecutingAssembly()
	  .GetCustomAttributes(typeof(ModuleAttribute), true)
	  .Cast<ModuleAttribute>()
	  .Select(t => Activator.CreateInstance(t));
Provide the proper assembly as required, and if you require that your
plugins implement an interface or inherit from a base class you could
cast to that interface/class within .Select().
 - Jon
    
    
More information about the Mono-list
mailing list