FileNotFoundException from DirectoryCatalog constructor

May 25, 2009 at 6:22 PM

I'm using a DirectoryCatalog and one of the *.dll files in the directory is causing the constructor to throw a FileNotFoundException on certain machines.

The stack trace shows that the exception occurs in ComposablePartCatalogCollection.cs on this line:

IEnumerable<ComposablePartDefinition> items = item.Parts.ToArray();

when called from DirectoryCatalog.Initialize():

this._catalogCollection.Add(assemblyCatalog);

I found it odd that DirectoryCatalog.CreateAssemblyCatalogGuarded() purposely ignored FileNotFoundException and yet another section of the code wouldn't. 

I added the same try/catch from CreateAssemblyCatalogGuarded within the DirectoryCatalog.Initialize() method's

foreach (string file in this._loadedFiles)

But obviously I don't want to rely on this change in the future. 

Comments/help?

Thanks.

 

Developer
May 26, 2009 at 5:20 PM

Interesting can you actually repro this consistently? What does the callstack look like when you get the FileNotFoundException? It would seem strange to be caused by item.Parts.ToArray() because that should be on an AssemblyCatalog which should have had the Assembly already loaded into the process thus it should always be found.

May 26, 2009 at 6:21 PM

Yes, on certain machins we can repro this consistently. There is an assembly in the directory we're creating the catalog for that has an unsatisfied reference, apparently.

The assembly gets an AssemblyCatalog instance created in the DirectoryCatalog.Initialize method's call to CreateAssemblyCatalogGuarded. But in AssemblyCatalog.get_Parts(), the call to this._assembly.GetTypes(), when constructing a new TypeCatalog, is what's failing.

The effect of this failure is that the DirectoryCatalog is never created. It would be better for the catalog to be created and ignore the invalid assemblies.

Here's the stack trace:

at System.Reflection.Module._GetTypesInternal(StackCrawlMark& stackMark)
at System.Reflection.Assembly.GetTypes()
at System.ComponentModel.Composition.Hosting.AssemblyCatalog.get_Parts()
at System.ComponentModel.Composition.Hosting.ComposablePartCatalogCollection.Add(ComposablePartCatalog item)
at System.ComponentModel.Composition.Hosting.DirectoryCatalog.Initialize(String path, String searchPattern)
at System.ComponentModel.Composition.Hosting.DirectoryCatalog..ctor(String path, String searchPattern)
at System.ComponentModel.Composition.Hosting.DirectoryCatalog..ctor(String path)