Yes, I’ve raised this with the MEF team many times. It’s easier to go and do it yourself.
The issue is that DirectoryCatalog does not guard against failures on loading types (which is quite common as soon as you start working on real projects as opposed to samples – hint hint!). So here’s a better version (in F#):
|cs |||copy code |||?|
type DirectoryCatalogGuarded(folder) =
let _catalogs = List
let mutable _parts : ComposablePartDefinition seq = null
let load_assembly_guarded (file:string) =
let name = AssemblyName.GetAssemblyName(file);
with | ex -> null
let guard_load_types (asm:Assembly) =
with | :? ReflectionTypeLoadException as exn -> exn.Types
let files = Directory.GetFiles(folder, "*.dll")
for file in files do
let asm = load_assembly_guarded file
if asm <> null then
let types = guard_load_types(asm) |> Seq.filter (fun t -> t <> null)
if not (Seq.isEmpty types) then
_catalogs.Add (new TypeCatalog(types))
_parts <- _catalogs |> Seq.collect (fun c -> c.Parts)
override x.Parts = _parts.AsQueryable()
override x.GetExports(definition) =
_catalogs |> Seq.collect (fun c -> c.GetExports(definition))
The “trick” is to catch ReflectionTypeLoadException – something I learned from David. This exception gives you a list of types it was able to load. Mind you, nulls may exists in the list hence the filtering.
The shortcoming here is that by bypassing the AssemblyCatalog, you wont be able to use CatalogReflectionContextAttribute – which I believe I’m one of the ten people on earth that knows what it’s for, so no biggy I guess?