Item 4 of 7 Previous | Next

1
Vote

Assembly.LoadFrom is still required

description

I've just updated to the version 54d64b40c923 and the problem with GrammarLoader failing to find and load dependent assemblies is still there (it throws a ReflectionTypeLoadException when you call GetTypes()).

Changing GrammarLoader.LoadAssembly() from Load(byte[]) to LoadFrom(filename) is still a workaround but it naturally destroys the reloading logic.

No files are attached

comments

yallie wrote Mar 10 at 5:47 PM

I've just simplified a bit the latest fixes. Please pull the latest changes from my fork.

rivantsov wrote Mar 9 at 6:34 PM

thanks! will look at it and pull it soon

yallie wrote Mar 9 at 12:16 AM

I've just improved auto-refresh feature:
1. Shadow copying of loaded assemblies is enabled, so Assembly.LoadFrom(fileName) doesn't lock the loaded file.
2. For the first time an assembly is always loaded using Assembly.LoadFrom(fileName) to enable standard dependency resolution.
3. If the standard loader returned an old version from the current AppDomain, then we reload it using Assembly.LoadFrom(byte[]).
4. If assembly resolution handler fails to locate the dependency, it asks the user to browse for a file, just like .NET Reflector does.
5. Refresh button is added: it's useful when Auto-refresh feature is disabled or the file system doesn't support change notifications.

P.S. Please note that these changes are currently available on my fork, IronyContrib.

rivantsov wrote Feb 4 at 3:23 PM

What if we use the checkbox AutoRefresh to decide which method to use? if it is checked, use Load from bytes; otherwise, use LoadFrom. Then everybody is happy

Peck797 wrote Feb 2 at 8:39 PM

Sorry for the delay; I got called elsewhere for a moment.

The code goes straight from where it does the Assembly.Load() (at the end of GrammarLoader.LoadAssembly) to where it explodes on calling GetTypes() (line 66 of frmSelectGrammars.cs). There's no flag being reset or anything, so I don't understand what you mean by "the resolver is disabled".

If I change your version to call LoadFrom(), then everything works fine.

If that doesn't make enough sense (it's a bit garbled because it's hard to describe when there's nothing much to talk about!). If not, can you point me at the code you think you're talking about and I'll take a look at it?

yallie wrote Feb 1 at 8:10 AM

Roman, you're not quite right... Dependency resolver is currently enabled while grammar is being loaded and created. If dependent assembly is required by the grammar constructor, it will be processed as well. If ReflectionTypeLoadException is thrown while calling GetTypes(), it means that dependency resolver was active and couldn't locate the assembly. So, it must be improved to support everything that standard probing algorithm does.

rivantsov wrote Jan 31 at 9:30 PM

I have a suggestion. It might be that the reason for failure (in improved version) is that we enable path lookup only while we are loading grammar type; once type is located, the resolver is disabled. However, the dependency may be activated when we start to execute the grammar constructor, and at this moment loader does not know about the path. The suggestion is to see if leaving path for lookup enabled indefinitely would help - and if yes, leave it there

yallie wrote Jan 31 at 9:07 PM

Looks like we should further improve dependency resolver.
Currently, it looks for dependent assemblies inside the same folder as your grammar assembly.
It doesn't check subfolders, application executable folder and GAC.
Please provide more details on your setup (it would be great if you can zip and attach your solution to this work item).