1

I am looking at how the runtime locates assemblies and am wondering whether there is a way to just get the path of an assembly found by Assembly.Load rather than actually loading it?

The reason I need this is because AssemblyDefinition.ReadAssembly from Mono.Cecil requires a path directly to the assembly and won't go to the extra effort of trying to locate it for itself. I'd like instead to combine the functionalities of standard System.Reflection and Mono.Cecil.

2
  • Have you tried Assembly.Location? Commented Nov 5, 2017 at 8:58
  • That would work, but then the assembly would be loaded into the application domain. I'd like to avoid that. Commented Nov 5, 2017 at 9:01

2 Answers 2

2

Mono.Cecil uses assembly resolvers to get an AssemblyDefinition from an assembly name.

AssemblyNameReference reference = AssemblyNameReference.Parse("Foo, Version=1.0.0.0");
DefaultAssemblyResolver resolver = new DefaultAssemblyResolver();
AssemblyDefinition foo = resolve.Resolve(reference);
Sign up to request clarification or add additional context in comments.

Comments

1

New Answer

You might be able to use AssemblyName. Unfortunately I'm not at my development machine so I can't test this. But AssemblyName is used in the mscorlib implementation of Assembly.Load().

I went diving into the CoreCLR to see if I could gain any insight into where the resolver actually looks for the file but was unsuccessful. If this doesn't work, you might try diving into the CLR yourself for answers. I narrowed it down to a FindAssembly call

var assemblyName = new AssemblyName("YourAssembly versionwhateveretc");
var path = new Uri(assemblyName.EscapedCodeBase).LocalPath;

Old Answer

Does ReflectionOnlyLoading work for you?

This should allow you to inspect/interact with the assembly metadata without fully loading it into the current AppDomain.

7 Comments

I tried it yesterday and got this exception: System.IO.FileLoadException: Cannot resolve dependency to assembly 'System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' because it has not been preloaded. When using the ReflectionOnly APIs, dependent assemblies must be pre-loaded or loaded on demand through the ReflectionOnlyAssemblyResolve event. I'd like to avoid actually loading assemblies if possible due to various complexities most of which I am not even sure what they are.
Is your concern performance related, or does loading the assembly cause issues with what you're trying to do? Another option is loading it into a new app domain to get the path, then close the app domain.
Good question. What I am trying to do is rewrite an interface module to the .NET API for a language that I am doing so it uses Mono.Cecil instead of the standard reflection. Right now I have the problem that compiling the types in just 4 assemblies takes roughly 0.6s which is insane. I haven't bothered measuring just how long loading the assemblies via standard reflection would take, but now that I've decided on a rewrite of the interop module I am trying as much as possible to avoid touching standard reflection.
The concern is performance related since obviously just finding the path of the assembly given its name should be much less expensive than loading it in its entirety.
I'm trying to find the code currently used to resolve assemblies. Unfortunately if the two options I provided aren't going to work you may have to reimplement the resolver in managed code for your usage.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.