5

I have assembly A referencing assembly B. They are located in the same directory.

Type[] types = null;
try
{
  Assembly a = Assembly.Load("A.dll");
  types = a.GetTypes(); // loads B implicitly.
}
catch(ReflectionTypeLoadException ex)
{
  types = ex.Types.Where(x=>x!=null);
}

How do I prevent B from being loaded? I want GetTypes() to run as if B wasn't available and to return only available types and null's for not available so I could execute ex.Types.where(x=>x!=null);

I want to use the trick from How to prevent ReflectionTypeLoadException when calling Assembly.GetTypes()

This way I can get only types that don't depend on B and work with them.

Update:

I loaded A in the reflection as well as in the normal context. I used the reflection context A for calling GetTypes(). After getting types from the reflection context assembly, I had another problem. When I called Type.GetCustomAttributes(), I received the following exception

It is illegal to reflect on the custom attributes of a Type loaded via ReflectionOnlyGetType (see Assembly.ReflectionOnly) -- use CustomAttributeData instead.

I solved it by getting the same type from the normal context assembly.

//... code omited for brevity
Type reflectionType = reflectionAssembly.GetTypes()[0];
//... code omited for brevity
Type goodType = normalAssembly.GetType(reflectionType.FullName);

This way I prevented loading of B and used types from A independent from B.

nathan gonzalez
  • 11,817
  • 4
  • 41
  • 57
evpo
  • 2,436
  • 16
  • 23
  • Erm, don't inherit from any types in B? Which makes preventing loading B rather pointless. – Hans Passant Feb 07 '12 at 01:03
  • The reason why I want to prevent B from loading is because I don't want the file to be locked so it can be compiled without restarting the application. It is used in some scenarios where it needs to be loaded. – evpo Feb 07 '12 at 01:09
  • So you want to change the base class of a derived class defined in A? There are languages that support this. They are in the dynamic language category, javascript, python, ruby. Runtime errors instead of compile-time errors. – Hans Passant Feb 07 '12 at 01:17
  • Assembly A is not used at this point. It is loaded as a part of initialisation. The list of types is needed for convention resolution in IOC. When types in A are used, B will be needed. I understand that. – evpo Feb 07 '12 at 01:24
  • Clearly that's not the way it works. Reflecting a type is very much *using* the type, even if you don't yet generate code for it. Code is meaningless to Reflection. – Hans Passant Feb 07 '12 at 01:37
  • I updated the question. By using that trick (see the link) you can reflect types partially. ReflectionTypeLoadException will only return types that don't derive from types in B. My bad. I didn't mention it at the beginning. – evpo Feb 07 '12 at 02:34

2 Answers2

8

look at using Assembly.ReflectionOnlyLoad() which looks to not load dependencies. not sure if it will return types that reference that dependency or not as i've not tried to do it before.

nathan gonzalez
  • 11,817
  • 4
  • 41
  • 57
  • Yes, it worked. It doesn't return the referencing types but you can get independent types, which is what I need. Thanks – evpo Feb 07 '12 at 03:36
0

It's 2022, and .NET 6 is here, so the solution mentioned above is officially obsolete.

Here is a new solution: https://github.com/dotnet/corefxlab/blob/master/docs/specs/typeloader.md

Apparently, this is an archived experimental repository, so you have to embed the code into your project manually. Take note of the license.

Sergey
  • 1,608
  • 1
  • 27
  • 40
AHpx
  • 24
  • 3
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Feb 11 '22 at 20:07