Find Types in All Assemblies
I need to look for specific types in all assemblies in a web site or windows app, is there an easy way to do this? Like how the controller开发者_JS百科 factory for ASP.NET MVC looks across all assemblies for controllers.
Thanks.
There are two steps to achieve this:
- The
AppDomain.CurrentDomain.GetAssemblies()
gives you all assemblies loaded in the current application domain. - The
Assembly
class provides aGetTypes()
method to retrieve all types within that particular assembly.
Hence your code might look like this:
foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies())
{
foreach (Type t in a.GetTypes())
{
// ... do something with 't' ...
}
}
To look for specific types (e.g. implementing a given interface, inheriting from a common ancestor or whatever) you'll have to filter-out the results. In case you need to do that on multiple places in your application it's a good idea to build a helper class providing different options. For example, I've commonly applied namespace prefix filters, interface implementation filters, and inheritance filters.
For detailed documentation have a look into MSDN here and here.
LINQ solution with check to see if the assembly is dynamic:
/// <summary>
/// Looks in all loaded assemblies for the given type.
/// </summary>
/// <param name="fullName">
/// The full name of the type.
/// </param>
/// <returns>
/// The <see cref="Type"/> found; null if not found.
/// </returns>
private static Type FindType(string fullName)
{
return
AppDomain.CurrentDomain.GetAssemblies()
.Where(a => !a.IsDynamic)
.SelectMany(a => a.GetTypes())
.FirstOrDefault(t => t.FullName.Equals(fullName));
}
Easy using Linq:
IEnumerable<Type> types =
from a in AppDomain.CurrentDomain.GetAssemblies()
from t in a.GetTypes()
select t;
foreach(Type t in types)
{
...
}
Most commonly you're only interested in the assemblies that are visible from the outside. Therefor you need to call GetExportedTypes() But besides that a ReflectionTypeLoadException can be thrown. The following code takes care of these situations.
public static IEnumerable<Type> FindTypes(Func<Type, bool> predicate)
{
if (predicate == null)
throw new ArgumentNullException(nameof(predicate));
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
{
if (!assembly.IsDynamic)
{
Type[] exportedTypes = null;
try
{
exportedTypes = assembly.GetExportedTypes();
}
catch (ReflectionTypeLoadException e)
{
exportedTypes = e.Types;
}
if (exportedTypes != null)
{
foreach (var type in exportedTypes)
{
if (predicate(type))
yield return type;
}
}
}
}
}
精彩评论