Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get all User-Created Classes in AppDomain.CurrentDomain

I want to loop over all classes which I have added in my project

Assembly[] foo = AppDomain.CurrentDomain.GetAssemblies();

foreach(Assembly a in foo)
{                
    foreach(Type t in a.GetTypes())
    {

    }
}

this is what I tried but I want to exclude the assemblies which are provided by .net, for example "mscorlib"

like image 818
Jan Avatar asked Jun 04 '12 12:06

Jan


2 Answers

One common solution would be to filter the assemblies by name, if all of your assemblies have a common prefix (if you have a more or less unique prefix).

var foo = AppDomain.CurrentDomain.GetAssemblies()
                                 .Where(a=>a.FullName.StartsWith("MyProject."));

If you are only interested in some specific types, consider using attributes for your classes, or even add one at assembly level.

Example:

Create an attribute:

[AttributeUsage(AttributeTargets.Assembly)]
public class MyAssemblyAttribute : Attribute { }

add the following to your AssemblyInfo.cs:

[assembly: MyAssemblyAttribute()]

and filter the assemblies you are looking at:

var foo = AppDomain.CurrentDomain
                   .GetAssemblies()
                   .Where(a => a.GetCustomAttributes(typeof(MyAssemblyAttribute), false).Any());

Also you will find at this question interesting. In one answer it is suggested to check the fully qualified name of each assembly, but this is quite tedious, e.g.:

//add more .Net BCL names as necessary
var systemNames = new HashSet<string>
{
    "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
    "System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
    ...
};

var isSystemType = systemNames.Contains(objToTest.GetType().Assembly.FullName); 

It's always easier to mark your assemblies (by name or attribute) than trying to identify which ones are part of the .Net framework.

like image 101
sloth Avatar answered Nov 15 '22 00:11

sloth


In one of my projects I need a list of classes used as business objects. These classes are always user-created types, but can be in a referenced assembly. They do not implement a specific interface and do not derive from a specific base class and do not have a distinctive attribute.

This is the code I use to filter useful types:

return
    type.IsClass && // I need classes
    !type.IsAbstract && // Must be able to instantiate the class
    !type.IsNestedPrivate && // Nested private types are not accessible
    !type.Assembly.GlobalAssemblyCache && // Excludes most of BCL and third-party classes
    type.Namespace != null && // Yes, it can be null!
    !type.Namespace.StartsWith("System.") && // EF, for instance, is not in the GAC
    !type.Namespace.StartsWith("DevExpress.") && // Exclude third party lib
    !type.Namespace.StartsWith("CySoft.Wff") && // Exclude my own lib
    !type.Namespace.EndsWith(".Migrations") && // Exclude EF migrations stuff
    !type.Namespace.EndsWith(".My") && // Excludes types from VB My.something
    !typeof(Control).IsAssignableFrom(type) && // Excludes Forms and user controls
    type.GetCustomAttribute<CompilerGeneratedAttribute>() == null && // Excl. compiler gen.
    !typeof(IControllerBase).IsAssignableFrom(type); // Specific to my project

Since my user types are not in the GAC !type.Assembly.GlobalAssemblyCache does a pretty good job in excluding most of BCL (Framework libraries) types and some third-party stuff.

This is not watertight, but works well my case. You will most likely need to tweak it for your needs.

like image 38
Olivier Jacot-Descombes Avatar answered Nov 15 '22 00:11

Olivier Jacot-Descombes