Kumar
Kumar

Reputation: 11349

Adding assemblies to catalog using MEF

Have a rather large project with nearly a dozen assemblies added to the shell and other assemblies added via config

Trying to find a better way to add assemblies referenced in the project

The code so far looks like this

 Dictionary<string,string> dict = new Dictionary<string,string>(); // to avoid duplicate parts
 foreach (Assembly an in AppDomain.CurrentDomain.GetAssemblies())
            addAssembly(an, dict);

 foreach (AssemblyName an in Assembly.GetEntryAssembly().GetReferencedAssemblies())
            addAssembly(an, dict);

 foreach (AssemblyName an in GetAsmInConfig())
            addAssembly(an, dict);

Even so, not all assemblies referenced at design time to Shell are added to the catalog

Wondering if there's anything short of adding all assemblies to config that will do the trick

UPDATE

  void addAssembly(Assembly a, Dictionary<string, string> dict)
    {
        if (a.IsDynamic || dict.ContainsKey(a.FullName))
            return;

        dict.Add(a.FullName, a.FullName);
        AggregateCatalog.Catalogs.Add(new AssemblyCatalog(a));        
    }

Upvotes: 4

Views: 6391

Answers (2)

Yaur
Yaur

Reputation: 7452

the compiler will remove refferences to that are not actually used so you can not rely on this as a mechanism to enumerate assemblies. Your options are to:

  1. use a config file
  2. use a directory catalog

Upvotes: 2

Gilles
Gilles

Reputation: 5407

From what I understand you are trying to get all assemblies (from appdomain, referenced by entry assembly and in a config file) in a dictionary and then supply this to MEF so that it looks for parts in those assemblies.

Instead of using this I would supply my CompositionContainer with an AggregateCatalog. Then I would create DirectoryCatalogs and supply the folder where said assemblies (dll) reside.

These could be the bin folder of the project which should already contain most dlls, plus any other folders you need (the ones where the assemblies currently specified in your config file reside).

Even better, I would create a /plugin or /parts directory in my bin folder. With post-build events (in project properties) I would copy all the dlls I need for parts which aren't already in my bin folder. Then I would do something like this:

var aggregateCatalog = new AggregateCatalog();

var mainDirectoryCatalog = new DirectoryCatalog(".");
var partsDirectoryCatalog = new DirectoryCatalog("./parts");

aggregateCatalog.Catalogs.Add(mainDirectoryCatalog);
aggregateCatalog.Catalogs.Add(partsDirectoryCatalog);

If you supply this aggregateCatalog to your CompositionContainer, all dlls from both of those directories will be scanned for parts. Since the entry assembly and it's referenced assemblies is already in the bin it would get those. The rest of the assemblies would be copied in the parts directory.

Upvotes: 2

Related Questions