InitializeModules incorrectly duplicating Exports

Topics: Prism v4 - Silverlight 4
Nov 16, 2010 at 3:28 PM

First, somebody had answered a thread and talked about a method of retrieving parts without relying on SatisfyImports but I haven't seen it.  Is that up or in the help for Prism 4.

Next, I have a common assembly that Exports ITruckService.

    public class TruckService : ITruckService

I make sure this is initialized into the this.AggregateCatalog.Catalogs via the bootstrapper.

This problem is modular and I have other modules that load and import ITruckService just fine.

However, the new Scanning module, I have a ViewModel which I've tried importing it in the constructor and as a property and it fails. 

The failure is another frustrating topic.  All I'm getting is that the module failed to load.  I have to go through every piece of the module and disable imports to try and track down the problem.

I finally tracked it down to this.

public ScanningMainViewModel(ITruckService truckService)

Makes no sense because in a separate Module it works just fine.

public TruckViewModel(ITruckService truckService)

I set a break point in the Bootstrapper's CreateContainer and the container contains ITruckService but yet it fails when my ScanningModule loads.

With no error to go off of, my hunch is something to do with Prism's ModuleInitializer.  So I went and changed the Import for ITruckService to ImportMany.

Sure enough now it works. 

        public IEnumerable<ITruckService> TruckService
            get { return _truckService; }
            set { _truckService = value; }

The problem is ITruckService should have not been exported more than once.  I've raised this problem before but got the usual blow off of post a sample.  This is a fairly large app but I posted a link to a base that is patterned after this.

Again, here's how my bootstrapper works.

My CreateContainer

protected override CompositionContainer CreateContainer()
            var _container = base.CreateContainer();
            // Necessary so export parts from EyeCue get added.
            this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(Bootstrapper).Assembly));
            // This is necessary so the parts of the EyeCue.Common get added.
            this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(GlobalValues).Assembly));

            // Initialize the container so parts are available in Modules when SatisfyImports is called.

            return _container;


My CreateModuleCatalog()

 protected override IModuleCatalog CreateModuleCatalog()
            IModuleCatalog _modCat = Microsoft.Practices.Prism.Modularity.ModuleCatalog.CreateFromXaml(new Uri(ModuleCatalogUri, UriKind.Relative));
            return _modCat;


My InitializeModules()

protected override void InitializeModules()
            IModuleManager _moduleManager = this.Container.GetExportedValue<IModuleManager>();
            _modulesToLoad = this.ModuleCatalog.Modules.Count();
            _moduleManager.LoadModuleCompleted += new EventHandler<LoadModuleCompletedEventArgs>(ModuleManager_LoadModuleCompleted);

Here's my ModuleCatalog file.

protected override IModuleCatalog CreateModuleCatalog()
            IModuleCatalog _modCat = Microsoft.Practices.Prism.Modularity.ModuleCatalog.CreateFromXaml(new Uri(ModuleCatalogUri, UriKind.Relative));
            return _modCat;


To summarize, why would me adding another module cause ITruckService which is part of a common assembly to get Exported 2 times.

I would think it has to do with something in the Prism InitializeModules() call but what and why?   Also, how would you go about changing this behavior.

I consider it a bug if there is not a way to configure.  Because 1) I'm not exporting multiple ITruckService classes, just one.  2) With it doing this in a modular app, if I don't use ImportMany's for everything, things stand to break depending on what modules I have loading.  Plus it invalidates ImportMany because you have to use it whether it's what you wanted or not.



Nov 16, 2010 at 3:50 PM

Is this a Silverlight app? and are the modules in separate XAPs?

If so, this is due to a quirk in how MEF imports things.  If you have the same DLL in two different XAPs, even if it is strongly typed, and it exports any types, MEF views the types as distinctly different types (one from each XAP), so they will be imported multiple times.  The simplest work around is to ensure that any dlls that export concrete types are only in one XAP, and the reference to the dll in all other projects has the Copy Local flag set to false.

If this is not a Silverlight app with separate Xaps, there may be something else going on.

Let me know if this helps or not



Nov 16, 2010 at 4:10 PM


I apologize but I marked it as Silverlight 4 and thought that would be portrayed.

Yes this is SL 4.

The main Silverlight xap is called EyeCue.xap.

I have a common assembly called EyeCue.Common and it is where ITruckService is exported.  It is a part of the Main application EyeCue.Xap.  EyeCue.Common is the only place I'll export anything that needs to be used by more than one module.  Otherwise the modules maintain their own Exports internally and none of the modules will contain references to each other. 

Each of my modules are their own xap file.  I have TruckStatModule, AppSettingModule & ScanningModule.

TruckStatModule has an Import for ITruckService but it does not see multiple parts for ITruckService.

I created ScanningModule and it has an import for ITruckService and it does see multiple exports for ITruckService.

Both TruckStatModule & ScanningModule have assembly references to EyeCue.Common and I do have the Copy Local for it in both modules set to false.  I actually set all assembly references Copy Local to false if they are used in the main .xap. 

So to recap, ITruckService is in a separate .xap from the modules, however the modules reference Copy Local is set to false.  Also, why does the TruckStatModule not see multiple ITruckService parts but my new ScanningModule sees more than 1?

Actually when I set a break point on the setter for the Property in my ScanningModule, value is an array but there it's only showing 1 element in the array.

This is what value looks like in the setter for the Import.

[EyeCue.Common.TruckSvc.ITruckService[]] = {EyeCue.Common.TruckSvc.ITruckService[0]}

Nov 17, 2010 at 9:52 PM

Ooops.  I should actually read the tags on these posts on occasion.

Thanks for the clarification of the issue.  I took the Modularity with MEF for Silverlight QS and hacked it a bit to try to reproduce this.

There are two different implementations I looked at:

  • I added a new Infrastructure project, which contains the IMyService interface and an implementation MySimpleService. In the bootstrapper, I add the Infrastrucutre DLL to the aggregate catalog.  In ModuleA and ModuleF, I import the service (in one via in ImportingConstructor and via a property in the other). If I do not set copylocal to false on ModuleF, I get exceptions thrown.  If I do set it, things work well.
  • I added a new Infrastructure project, which only contains the IMyService interface.  I also added a ServiceImplementation project that has a class that implements and exports the IMyService interface. In the bootstrapper, I add the ServiceImplementation DLL to the aggregate catalog. In ModuleA and ModuleF, I import the service (in one via in ImportingConstructor and via a property in the other). In this case, the modules only reference the DLL with the interface defined, so there are no copylocal settings to change.

And based on my understanding of MEF, this is what I expected. Which of these better matches the scenario you are attempting? Or did I miss something from your above that has me far off base?

I see a few things to try:

I would double check all the references to the dll that has the concrete implemntation of the service.

If that does not help, grab one of the MEF visualizers to help with debugging.

Another option, if you want to change the default behavior, could be to specialized the MefModuleManager ModuleTypeLoaders property, providing a custom implementation (probably based on the MefXapModuleTypeLoader) that filters out types being loaded before MEF can get ahold of them, so you can ensure that types do not get loaded more than once.  In an earlier drop of Prism v4 (around drop 5, I think) we did something like this, but it was a little ugly.

Or you could use Unity where things are a bit more explicit and different "magic" happens behind the scenes. :-)



Nov 17, 2010 at 10:22 PM

I would say it more closely matches item 1.

ModuleTemplate.rar is there and if you start adding new modules I would imagine you can see what I'm dealing with.

I've rechecked the CopyLocal and it's false on all dll's.

I also have IPopuController in my Common assembly. I had a similar before I ran into this one. When I had one module, there was only one part for it. I Import IPopupController in my main Silverlight Xap.

When I added a second module it started throwing an exception and I had to change it to ImportMany.

Honestly, I wish I hadn't bought into MEF or at least until they work out the problems of implementing and debugging. But it's integrated now and I need to figure this out without going back and ripping things out and wasting time learning how to get it to work with dynamically loading xap files.