Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Any Way to "Safely" Call assembly.GetTypes()?

Tags:

I've searched high and low, but I can't come up with a solution for this.

I need to get all the interface types from an assembly with code like this:

IEnumerable<Type> interfaces = _assembly.GetTypes().Where(x => x.IsInterface); 

The problem is, for certain assemblies I run into the following error:

Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.

I'm completely clear on why this happens (dependant assemblies are not loaded), and how it can be worked around if I want to troubleshoot a specific assembly. In my case, I don't know the assembly up front (the user will select it).

What I'd like to know is whether there is any way to allow the code to continue past any types that can't be retrieved, and still pull the ones that don't fail.

like image 680
Phil Sandler Avatar asked Apr 12 '11 17:04

Phil Sandler


1 Answers

It looks like this is a vexing API for which the exception cannot be avoided (as far as I know).

Try something like this:

IEnumerable<Type> interfaces; try {     interfaces = _assembly.GetTypes().Where(x => x.IsInterface); } catch (ReflectionTypeLoadException ex) {     interfaces = ex.Types.Where(x => x != null && x.IsInterface); } 

UPDATE

Actually, this is so ugly that I would probably hide it somewhere. This must be a very old part of the .NET Framework, because I’m pretty sure they wouldn't design it like this nowadays.

private static IEnumerable<Type> GetTypesSafely(Assembly assembly) {     try     {         return assembly.GetTypes();     }     catch(ReflectionTypeLoadException ex)     {         return ex.Types.Where(x => x != null);     } }  ... IEnumberable<Type> interfaces = GetTypesSafely(_assembly).Where(x => x.IsInterface); 

If you think you'll be doing this very often, then an extension method might be more appropriate.

like image 52
Jeffrey L Whitledge Avatar answered Nov 03 '22 20:11

Jeffrey L Whitledge