[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