C#: List All Classes in Assembly

C#: List All Classes in Assembly

Use Assembly.GetTypes. For example:

Assembly mscorlib = typeof(string).Assembly;
foreach (Type type in mscorlib.GetTypes())
{
Console.WriteLine(type.FullName);
}

List of classes in an assembly C#

Here's a little class I whipped up some weeks back when I was bored, this does what you're asking of - if I understand the question correctly.

Your applications must implement IPlugin, and must be dropped in a "Plugins" folder in the executing directory.

public interface IPlugin
{
void Initialize();
}
public class PluginLoader
{
public List<IPlugin> LoadPlugins()
{
List<IPlugin> plugins = new List<IPlugin>();

IEnumerable<string> files = Directory.EnumerateFiles(Path.Combine(Directory.GetCurrentDirectory(), "Plugins"),
"*.dll",
SearchOption.TopDirectoryOnly);

foreach (var dllFile in files)
{
Assembly loaded = Assembly.LoadFile(dllFile);

IEnumerable<Type> reflectedType =
loaded.GetExportedTypes().Where(p => p.IsClass && p.GetInterface(nameof(IPlugin)) != null);

plugins.AddRange(reflectedType.Select(p => (IPlugin) Activator.CreateInstance(p)));
}

return plugins;
}
}

Following from Paul's recommendation in the comments, here's a variation using MEF, referencing the System.ComponentModel.Composition namespace.

namespace ConsoleApplication18
{
using System;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.IO;
using System.Linq;

public interface IPlugin
{
void Initialize();
}
class Program
{
private static CompositionContainer _container;
static void Main(string[] args)
{
AggregateCatalog catalog = new AggregateCatalog();
catalog.Catalogs.Add(new DirectoryCatalog(Path.Combine(Directory.GetCurrentDirectory(), "Plugins")));

_container = new CompositionContainer(catalog);

IPlugin plugin = null;
try
{
_container.ComposeParts();

// GetExports<T> returns an IEnumerable<Lazy<T>>, and so Value must be called when you want an instance of the object type.
plugin = _container.GetExports<IPlugin>().ToArray()[0].Value;
}
catch (CompositionException compositionException)
{
Console.WriteLine(compositionException.ToString());
}

plugin.Initialize();
Console.ReadKey();
}
}
}

and the DLL file - also referencing the System.ComponentModel.Composition namespace to set the ExportAttribute

namespace FirstPlugin
{
using System.ComponentModel.Composition;

[Export(typeof(IPlugin))]
public class NamePlugin : IPlugin
{
public void Initialize() { }
}
}

How to find all classes in an assembly that are an instance of a generic abstract class and implement a certain interface

Your problem is actually quite complex to grasp.

The problem is that your class is derived from a generic class, whose generic argument implements the IHttpHandler.

You need to get the inherited (base) type (because you inherit from it).

That's a generic type, so you need to check if it's a generic type.

If it es, you need to get the generic type (GetGenericTypeDefinition).

Then you need to check if the generic type is of type HandlerMiddleware<>

Then you need to get the argument from the generic type.

Then you need to check the first generic argument (if it has one).

Then you need to check if that generic argument's type (or it's derivation base) implements the interface in question.

So in your case:

var ls = FindDerivedTypes(t.Assembly, typeof(HandlerMiddleware<>), typeof(IHttpHandler));
System.Console.WriteLine(ls);

public static List<System.Type> FindDerivedTypes(Assembly assembly
, System.Type typeToSearch
,System.Type neededInterface)
{
List<System.Type> ls = new List<System.Type>();

System.Type[] ta = assembly.GetTypes();

int l = ta.Length;
for (int i = 0; i < l; ++i)
{
if (ta[i].BaseType == null)
continue;

if (!ta[i].BaseType.IsGenericType)
continue;

// public class Middleman : IHttpHandler
// public class HelloWorldHandler2 : HandlerMiddleware<Middleman>
// public class HelloWorldHandler : HandlerMiddleware<HelloWorldHandler>, IHttpHandler

var gt = ta[i].BaseType.GetGenericTypeDefinition();
if (gt == null)
continue;

if (!object.ReferenceEquals(gt, typeToSearch))
continue;

Type[] typeParameters = ta[i].BaseType.GetGenericArguments();
if (typeParameters == null || typeParameters.Length < 1)
continue;

if(neededInterface.IsAssignableFrom(typeParameters[0]))
ls.Add(ta[i]);
} // Next i

return ls;
} // End Function FindDerivedTypes

And that's how you get that list.

Create a list of all classes in namespace using reflection and cast to their real type

SOLVED: The issue was I had internal constructors and the System.Activator couldn't create an instance of the class.

Getting All Classe names in a project

The two previous posters are correct. However, if you wanted a list of all referenced assemblies and their types, you could do:

var referencedAssemblies = Assembly.GetExecutingAssembly().GetReferencedAssemblies();
var referencedTypes = referencedAssemblies.SelectMany(x => Assembly.Load(x.FullName).GetTypes());

This would give a list of all Types from the core libraries, third-parties etc which are referenced and used, if you are not using an assembly but have it referenced it wouldn't list its types.

It isn't greatly useful as it lists thousands of types from System and System.Core etc, but i'm not entirely sure what you're trying to achieve, so it may be a start.

List of classes in an assembly

See the documentation for System.Reflection.Assembly.GetTypes() and
System.Type.GetMembers()

--larsw

How to get all classes in current project using reflection?

Given an instance a of System.Reflection.Assembly, you can get all types in the assembly using:

var allTypes = a.GetTypes();

This will give you all types, public, internal and private.

If you want only the public types, you can use:

var publicTypes = a.GetExportedTypes();

If you are running this code from within the Assembly itself, you can get the assembly using

var a = Assembly.GetExecutingAssembly();

GetTypes and GetExportedTypes will give you all types (structs, classes, enums, interfaces etc.) so if you want only classes you will have to filter

var classes = a.GetExportedTypes().Where(t => t.IsClass);

C# Get List of All Classes with Specific Attribute Parameter

You can just add this to your query:

where type.GetCustomAttribute<GenericConfigAttribute>().MyEnum == GenericConfigType.Type1

For example:

var type1Types =
from type in Assembly.GetExecutingAssembly().GetTypes()
where type.IsDefined(typeof(GenericConfigAttribute), false)
where type.GetCustomAttribute<GenericConfigAttribute>().MyEnum
== GenericConfigType.Type1
select type;

Or simplified slightly (and safer):

var type1Types =
from type in Assembly.GetExecutingAssembly().GetTypes()
where type.GetCustomAttribute<GenericConfigAttribute>()?.MyEnum
== GenericConfigType.Type1
select type;

And if you need to cope with multiple attributes on the same type, you can do this:

var type1Types =
from type in Assembly.GetExecutingAssembly().GetTypes()
where type.GetCustomAttributes<GenericConfigAttribute>()
.Any(a => a.MyEnum == GenericConfigType.Type1)
select type;

How can I get all classes within a namespace?

You will need to do it "backwards"; list all the types in an assembly and then checking the namespace of each type:

using System.Reflection;
private Type[] GetTypesInNamespace(Assembly assembly, string nameSpace)
{
return
assembly.GetTypes()
.Where(t => String.Equals(t.Namespace, nameSpace, StringComparison.Ordinal))
.ToArray();
}

Example of usage:

Type[] typelist = GetTypesInNamespace(Assembly.GetExecutingAssembly(), "MyNamespace");
for (int i = 0; i < typelist.Length; i++)
{
Console.WriteLine(typelist[i].Name);
}

For anything before .Net 2.0 where Assembly.GetExecutingAssembly() is not available, you will need a small workaround to get the assembly:

Assembly myAssembly = typeof(<Namespace>.<someClass>).GetTypeInfo().Assembly;
Type[] typelist = GetTypesInNamespace(myAssembly, "<Namespace>");
for (int i = 0; i < typelist.Length; i++)
{
Console.WriteLine(typelist[i].Name);
}

How enumerate all classes with custom class attribute?

Yes, absolutely. Using Reflection:

static IEnumerable<Type> GetTypesWithHelpAttribute(Assembly assembly) {
foreach(Type type in assembly.GetTypes()) {
if (type.GetCustomAttributes(typeof(HelpAttribute), true).Length > 0) {
yield return type;
}
}
}


Related Topics



Leave a reply



Submit