Search code examples
c#clickoncemef

ClickOnce issue with MEF


I've got a fairly complex wpf application that use MEF to load optional components. This works just fine with a standard installer.

I'm trying to get this working using ClickOnce deployment and when the application is suppose to import possible MEF components, I get an exception :

System.ComponentModel.Composition.CompositionException: The composition produced a single composition error. The root cause is provided below. Review the CompositionException.Errors property for more detailed information.

1) The remote server returned an error: (404) Not Found.

Resulting in: An exception occurred while trying to create an instance of type 'Client.Map.GeneralXamlMap.GeneralMapViewModel'.

Resulting in: Cannot activate part 'Client.Map.GeneralXamlMap.GeneralMapViewModel'. Element: Client.Map.GeneralXamlMap.GeneralMapViewModel --> Client.Map.GeneralXamlMap.GeneralMapViewModel --> AssemblyCatalog (Assembly="Client.Map.GeneralXamlMap, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null")

Resulting in: Cannot get export 'Client.Map.GeneralXamlMap.GeneralMapViewModel (ContractName="Client.Core.Core.Map.IMapViewModel")' from part 'Client.Map.GeneralXamlMap.GeneralMapViewModel'. Element: Client.Map.GeneralXamlMap.GeneralMapViewModel (ContractName="Client.Core.Core.Map.IMapViewModel") --> Client.Map.GeneralXamlMap.GeneralMapViewModel --> AssemblyCatalog (Assembly="Client.Map.GeneralXamlMap, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null")

I've checked the local folder, and the dll with the export is in the folder as expected. The code used to find the export is this :

public static IMapViewModel FindMap(string exportMetadataMapName)
    {            
        var catalog = new AggregateCatalog();
        catalog.Catalogs.Add(new AssemblyCatalog("Client.Map.GeneralXamlMap.dll"));
        CompositionContainer container = new CompositionContainer(catalog);
        MapFactory f = new MapFactory();
        container.ComposeParts(f);

        foreach (Lazy<IMapViewModel, IMapMetaData> item in f.maps)
        {
            if (item.Metadata.Name.Equals(exportMetadataMapName))
            {
                return item.Value;
            }
        }

        return null;        
    }

Any ideas ?

Update: I don't know why i didn't see this before, but the component I'm trying to load is a wpf usercontrol that loads an image from a URL. When I remove that url it works. Can this be security related ? The Click Once installer is a full trust.


Solution

  • OK, so i finally found it. I'll leave a quick solution for anyone interested.

    After a bit of digging around I found that it wasn't the MEF implementation that caused the problem, but a MEF component with a faulty implementation. One of the components merge a resource dictionary runtime and that dictionary was loaded using the URI "pack://siteoforigin..." When the application was deployed using ClickOnce, site of origin was the webserver and the application then did a httpget to the webserver to get the file in the uri, resulting in a 404 error.