none
Where do I find a list of things that can go wrong with MEF? RRS feed

  • Question

  • From the demo I thought MEF would be easy to use so I wrote the whole program, all the unit tests etc, leaving the testing of the MEF part (which looked like a no brainer to use) for integration testing.
    Well the whole program is now done and all parts are unit tested but when I run it I get 'No MyInterface Plugins found'.

    I start, in separate projects, by creating 2 dlls implementing an interface

        [Export(typeof(MyInterface))]
        public class SomeImplementation : MyInterface {...}

        [Export(typeof(MyInterface))]
        public class AnotherImplementation : MyInterface {...}

    In my main application project I create a class instance variable

        class Program
        {
            [ImportMany(typeof(MyInterface))]
            List<MyInterface> Implementations { get; set; }

    Then in Program.Main() I've got this code

                var dCatalog = new DirectoryCatalog(Directory.GetCurrentDirectory(), "*Implementation*.dll");
                var container = new CompositionContainer(dCatalog);
                Program p = new Program();
                container.ComposeParts(p);

    When I break on the ComposeParts line dCatalog.LoadedFiles shows both dlls and dCatalog.Parts has 2 ComposablePartDefinitions named 'MyInterface'.  (So far so good.)

    At this point the Implementations variable is still null.
    After ComposeParts executes, Implementations is no longer null, but the list itself is empty (Implementations.Count == 0).
    Where do I start with what can go wrong?

    Thanks

    Monday, February 11, 2013 10:37 PM

Answers

  • OK, so I found the problem.

    #1 - Make sure you really know which assemblies are actually being loaded.  Not just that they came from such-and-such a location and the location is correct but that the dlls in that location are in fact the ones you expect should be there.
    #2 - Next, there is what I would call a bug in MEF whereby it will not throw the 'No valid exports were found that match the constraint' exception when it finds a perfectly valid export with the contract name you are importing, on a class where the contract name is specified by string value.

    You might wonder why I think this is a problem.
    Well it considers this a satisfactory match but then doesn't instantiate the class into your ImportMany collection.
    Thus it finds your implementations and creates the collection but puts no instances into it and reports no errors.

    • Marked as answer by TaclGuru Tuesday, February 12, 2013 5:49 PM
    Tuesday, February 12, 2013 5:49 PM

All replies

  • Hi TaclGuru,

    I am not sure,but may be due to some reason your main application is not able to find your plugins. May be you can use something like below code

       var catalog = new AggregateCatalog(
                                        new AssemblyCatalog(Assembly.GetEntryAssembly()),
                                        new AssemblyCatalog(this.GetType().Assembly),
                                        new DirectoryCatalog(AppDomain.CurrentDomain.BaseDirectory));

    If it not help you,Please provide some more information or your code here to check actual problem.

    may be it helps you.
    If anything is unclear feel free to ask me... :)

    Thanks,
    Nans11


    ENjoy ThE WorLD Of COdE

    Tuesday, February 12, 2013 7:40 AM
  • As I said, I see both dlls when I look at dCatalog.LoadedFiles.  I also see 'MyInterface' listed in both parts in dCatalog.Parts ExportDefinitions.ComposablePartDefinitions.ContractName.  It certainly looks like it is finding them to me.  I don't see where your code looks for them.  Moreover, Main() is static so it doesn't have a 'this', meaning your example doesn't even compile in my scenerio.

    I'm not clear on what more actual code has any relevance in order to provide it.  The interface implementations simply provide methods that operate on method parameter data so the implementations of 'MyInterface' have no instance data, no imports of their own and no need of any initialization code much less construction parameters.

    Also, I ran mefx against the dlls and it shows my exports and no rejections.
    When I run it against the .exe I get an error of:
    An attempt was made to load a program with an incorrect format.

    Which is a nonsense error to me since the .exe runs and has no warnings during compile.

    Another clue (hopefully) is that the call to ComposeParts doesn't throw.  When I remove the dlls that call throws with 'No valid exports were found that match the constraint'

    • Edited by TaclGuru Tuesday, February 12, 2013 4:31 PM More troubleshooting results
    Tuesday, February 12, 2013 1:46 PM
  • OK, so I found the problem.

    #1 - Make sure you really know which assemblies are actually being loaded.  Not just that they came from such-and-such a location and the location is correct but that the dlls in that location are in fact the ones you expect should be there.
    #2 - Next, there is what I would call a bug in MEF whereby it will not throw the 'No valid exports were found that match the constraint' exception when it finds a perfectly valid export with the contract name you are importing, on a class where the contract name is specified by string value.

    You might wonder why I think this is a problem.
    Well it considers this a satisfactory match but then doesn't instantiate the class into your ImportMany collection.
    Thus it finds your implementations and creates the collection but puts no instances into it and reports no errors.

    • Marked as answer by TaclGuru Tuesday, February 12, 2013 5:49 PM
    Tuesday, February 12, 2013 5:49 PM
  • Are all the 4 assemblies (main executable, contract dll and 2 implementation dlls) located in the same folder? Make sure they're not using different copies of contract dll.
    Wednesday, February 13, 2013 4:34 AM