ViewRegistrationException (Another scenario)

Topics: Prism v4 - Silverlight 4
Mar 18, 2011 at 4:39 PM

I am experimenting with the ViewSwitchingNavigation sample.  What I am trying to accomplish is the following:

1.) Add a contracts library to the solution (Contracts) that contains one interface:

interface ITest { string Name { get; set; }}

2.) Add a shared library to the solution (Shared - contains references to System.ComponentModel.Composition and Contracts) that contains one class:

[Export] public class Test : ITest { public string Name { get; set; }}

3.) Add references to the Contracts and Shared libraries in the ViewSwitchingNavigation Project

4.) Add a reference to the Contracts library in the ViewSwitchingNavigation.Email project

5.) In the ViewSwitchingNavigation.Email project, add the following statements to the EmailNavigationItemView.cs file:

[Import] public ITest TestInstance;

 

So what I'm attempting to achieve is the following:

1.) Email project should not have any dependency on shared library, only on interfaces (Contracts project). 

2.) Shell project should plug in concrete instance of ITest at runtime (which it obtains from Shared project), when requested by EmailNavigationItemView.

However, when I run the project after making said changes, I get the ViewRegistrationException exception.

In the debug window, I'm also getting the infamous MEF exception: 

1) No valid exports were found that match the constraint '((exportDefinition.ContractName == "Contracts.ITest") AndAlso (exportDefinition.Metadata.ContainsKey("ExportTypeIdentity") AndAlso "Contracts.ITest".Equals(exportDefinition.Metadata.get_Item("ExportTypeIdentity"))))', invalid exports may have been rejected.

What am I forgetting to do?  Do I need to have the bootstrapper add the Shared library to the AssemblyCatalog or similar?  Thanks!

 

Mar 18, 2011 at 4:51 PM

Problem solved.  I was thinking that the issue had to do with the way I had my projects setup and how they referenced other assemblies. 

Step 2 above should be:

[Export(typeof(ITest))] public class Test : ITest { public string Name { get; set; }}

Apparently I don't know MEF as well as I thought I did.  Hopefully this helps someone...

Mar 18, 2011 at 5:04 PM
Edited Mar 18, 2011 at 5:06 PM

Ok, now I took the same concept and applied it towards the ModularityWithMef project.  The only difference is that I added a reference to the Contracts library in the ModuleF project, and added the following statement to ModuleF.cs:

[Import] public ITest TestInstance;

And of course, ModuleF won't load and the application crashes.  This is really the behavior I need (dynamic downloads and having the shell satisfy imports on the dynamically downloaded module)

"Unable to locate the module with type 'ModuleF.ModuleF, ModuleF, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' among the exported modules. Make sure the module name in the module catalog matches that specified on ModuleExportAttribute for the module type."

Any thoughts?

Mar 18, 2011 at 6:32 PM

Another update.  If I move the Test class from the Shared project to the ViewSwitchingNavigation project, the Import in the ModuleF class is successfully satisified.

Hoping someone can shed light as to why the ModuleF.ITest cannot be satisfied when the Test class is contained within the Shared project.

Developer
Mar 18, 2011 at 6:55 PM

Hi,

The problem you're experiencing could be caused by the fact that you haven't added the AssemblyCatalog containing your Test export to the AggregateCatalog.

You could try adding a reference to the Shared and Contracts assemblies in your shell project, and add a line like the following to the ConfigureAggregateCatalog method override in your bootstrapper class:

this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(Shared.Test).Assembly));

I hope you find this helpful.

Guido Leandro Maliandi 
http://blogs.southworks.net/gmaliandi

Mar 18, 2011 at 6:59 PM

Problem solved.  again.  Here's what I didn't do that needed to be done:

1.) Add a class the the Shared project that implements IModule (I named the class SharedModule)

2.) Apply the [ModuleExport] attribute to the SharedModule class

3.) Add the following line of code to the ConfigureAggregateCatalog() method of the QuickstartBootstrapper classs in the ViewSwitchingNavigation project:

this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(Shared.SharedModule).Assembly));

Having done that, I can now use a standalone library that my plug-ins do not need to reference and whose classes do not need to reside in the Shell's project.

 

 

Developer
Mar 18, 2011 at 7:10 PM

Hi,

You don't necessarily have to create a module in order to access to shared exports. By just adding the assembly catalog it should be enough for you to be able to access the exports defined in that class from within other modules.

I hope you find this helpful.

Guido Leandro Maliandi 
http://blogs.southworks.net/gmaliandi

Mar 18, 2011 at 7:28 PM

Guido, this was very helpful.  It's good to know that the IModule is not needed.  Thanks much!