Search code examples
c#mef

MEF Throws CompositionContractMismatchException


When composing or using ExportProvider.GetExportedValues Method. Exception CompositionContractMismatchException is thrown. I'm converting legacy code that was sprinked with static factories, so I simply want to expose there return values to MEF container, for example.

namespace fooProject
{
    static class SomeExportFactory
    {
        [Export(typeof(IFoo))]
        public static FooImp Generate()
        {
           return new FooImp();
        }
    }
}

So, this simple illustration would throw an exception with this message "Cannot cast the underlying exported value of type 'fooProject.SomeExportFactory.Generate (ContractName="IFoo")' to type 'IFoo'." to type "IFoo".].

Any guesses to what could be causing this? I already scoured the internet and CompositionContractMismatchException when trying to use MEF with MVC controller is the closes thing I can find, but I do not have duplicate assemblies like in that case.


Solution

  • Ok, I found the answer. Don't export from static functions!!!. Hope this helps someone else in this situation.

    MEF throws a cryptic exception if you are trying to exporting from a static function. The exception looks like a potentially duplicate assemblies loaded. Like some answers have suggested, but alas.

    For people that are interested in more details read on (links to current MEF implementations are provided). The code brakes down at ContractServices.cs. You will find a public static function "TryCast" there. It provides a mechanism for MEF to provide instance of the object boxed to a specified type. But it only checks for 2 conditions. First, the object passed in, is already of desired type. Second, object is provided through ExportedDelegate (probably how member function Export works). If your export does not fit any of these then false is returned and immediately CompositionContractMismatchException is thrown (see ExportServices.cs T CastExportedValue(ICompositionElement element, object exportedValue) function).

    I wish they would have throw DummyDontUseStaticException in this situation :p