Query catalog using type name

Feb 26, 2010 at 5:40 AM
Edited Feb 26, 2010 at 6:01 AM

I am just getting started with MEF.  I am trying to create a modular ASP.NET MVC application.  The idea is to create the MEF container at app startup much like you would an IOC container, and pass the MEF catalog to my controller factory.  The controller factory would query the MEF container in a way simliar to the way MVC locates controllers - by looking for classes that implement System.Web.Mvc.Controller and end in "Controller" - for example "MyApp.HomeController".  Ya know - convention over configuration and all that jazz.

Problem is, I can not query my MEF catalog for the names of the types in the catalog.

What I would love to be able to do is something like the following:

 
var w = Container.GetExports<ColabNVController, IPluginMetaData>(); 

var z = from v in w
let metadata = v.Metadata 
where metadata.Name == "Plugin1" 
& v.Value.ToString().EndsWith("HomeController")
 select v; 

return z.First().Value; 


I think the above will work, but it would create an instance of every controller when it evaluates the expression - not a good thing.  

I have created a "PluginAttribute" based off "InheritedExportAttribute" so I could pass in a "Plugin" value, and I suppose I could modify that so I could also pass in the controller name.  But, I would prefer to just have to put that "PluginAttribute" on a single base class for an entire plugin.

 

Poking around, it looks like I might be able to do something by working with the CompositionContainer Catalog.Parts - but I don't know if that is supported or not. 

Any ideas?

Feb 26, 2010 at 11:02 AM

Since you already use meta data in your example, I suggest that you eliminate the "v.Value.ToString().EndsWith("HomeController") check and instead put all information necessary for controller selection in the meta data. Like that, you will not have unnecessary instantiations. AFAIK that's the reason why there is a concept of meta data in MEF in the first place.

Feb 26, 2010 at 1:43 PM

That will work - I have my application working that way right now.  But I do not like doing it that way. 

I would like to keep the convention that ASP.NET MVC already has - Just make sure your controller names end in "Controller". 

I suppose after sleeping on it, I think one thing I may look into is see what extensibility points are available around catalog creation.  If I could say, create a metadata value called "Controller", but auto populate it at catalog creation time based on the class name, instead of having to tag each controller with an attribute,  I could be happy with that. 

 

Developer
Feb 26, 2010 at 5:20 PM

Hammett posted a sample MVC catalog that does what you are interested in at http://blogs.msdn.com/hammett/archive/2009/04/23/mef-and-asp-net-mvc-sample.aspx. That should at least get you started on what you are attempting to do.

Feb 27, 2010 at 2:42 PM

Thanks - it looks like that post is going to get me pretty close to what I need.