[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