MEF

11 views
Skip to first unread message

Peter O'Hanlon

unread,
Dec 14, 2009, 4:08:00 PM12/14/09
to wpf-di...@googlegroups.com
The more I use MEF, the more I love it. So, I've got this code in my App.xaml file:
 
protected override void OnStartup(StartupEventArgs e)
{
  base.OnStartup(e);
  AggregateCatalog catalog = new AggregateCatalog();
  catalog.Catalogs.Add(
new AssemblyCatalog(Assembly.GetExecutingAssembly()));
  string path = System.IO.Path.Combine(NativeMethods.StartupPath(), "Plugins");
  catalog.Catalogs.Add(
new DirectoryCatalog(path));

  _container = new CompositionContainer(catalog);
 
CompositionBatch batch = new CompositionBatch();
 
// We've put an Import on the MainWindow so that we can add this to the composition batch.
 
batch.AddPart(this);
  _container.Compose(batch);
  MainWindow.Show();
}

Now, all I do is drop in code into the Plugins directory and it just works. Really, that's what I want the tagline for MEF to be - It Just Works. Thanks guys, I appreciate the pain you've taken away. Now Goldlight quite happily moves task dialog and KTM code out from the main library into a services library.

--
Peter O'Hanlon

Josh Smith

unread,
Dec 14, 2009, 4:13:27 PM12/14/09
to wpf-di...@googlegroups.com
I agree.  MEF is great.  It's non-intrusive and simple.  That's all I care about, and oh yeah, it works too ;)

Laurent Bugnion

unread,
Dec 14, 2009, 5:05:45 PM12/14/09
to wpf-di...@googlegroups.com
Me too, very seduced by MEF. I used it in a prototype to load modules by dropping them in a folder, and also by loading XAPs with skins within, to offer multiple skins to the user.

Note that in Preview 8 for SL, you don't need to create the catalogs yourself, instead you can use PartInitializer and PackageService to make it even easier. I can pass you a sample if you want (need to blog about it, but with the book going on...)

In my prototype i used a DuplexService to notify the SL app when a new package is available in the server folder, so the SL app can initiate the download without the user having to do anything ;)

Cheers,
Laurent
--
Sent from mobile

Peter O'Hanlon

unread,
Dec 14, 2009, 5:08:03 PM12/14/09
to wpf-di...@googlegroups.com
Sounds cool.
--
Peter O'Hanlon

Shawn Wildermuth

unread,
Dec 14, 2009, 5:27:55 PM12/14/09
to wpf-di...@googlegroups.com

I am using the RIA Services/Silverlight 4 Exemplar I am working on and even though I am doing everything in the XAP (not loading XAPs dynamically), the hooking up of the models to the VM's to the Views is pretty awesome.  For example:

 

  [PartCreationPolicy(CreationPolicy.Shared)] // For singleton

  [Export(typeof(IGamesModel))]

  public class GamesModel : IGamesModel

  {

 

// ...

 

  [Export(typeof(IGameEditorViewModel))]

  public class GameEditorViewModel : MyViewModelBase, IGameEditorViewModel

  {

    private IGamesModel _model;

 

    [ImportingConstructor]

    public GameEditorViewModel(IGamesModel theModel)

    {

      _model = theModel

 

// ...

 

  public partial class GameListView : UserControl

  {

    public GameListView()

    {

      InitializeComponent();

 

      // Use MEF To load the View Model

      PartInitializer.SatisfyImports(this);

 

    }

 

    [Import(typeof(IGameListViewModel))]

    public IGameListViewModel ViewModel

    {

      set

      {

        DataContext = value;

      }

    }

 

// ...

Sacha Barber

unread,
Dec 15, 2009, 3:44:39 AM12/15/09
to wpf-di...@googlegroups.com
Yeah MEF rocks, way better than MAF (al be it they are doing slightly different things)
--
Sacha Barber
sacha....@gmail.com

Glenn Block

unread,
Dec 20, 2009, 2:26:59 AM12/20/09
to wpf-di...@googlegroups.com
Hey Shawn, by default all parts will have a creation policy of any which translates to shared. You should only need to specify the policy if you want to change to non-shared. In the case of ViewModels I would imagine in most cases you want non-shared rather than shared. i.e. if you have an OrderVM you would expect to have multiple instances (multiple orders open at the same time).

Nice article btw, I am planning to comment on it.

Regards
Glenn

Glenn Block

unread,
Dec 20, 2009, 2:27:55 AM12/20/09
to wpf-di...@googlegroups.com
Wheew, glad you are all liking it. We definitely had a goal of NOT doing something like MAF.

Glenn

Glenn Block

unread,
Dec 20, 2009, 2:34:38 AM12/20/09
to wpf-di...@googlegroups.com
Peter you should even have to specify the path like that if it is relative to your bin....

You could jjust do...

var catalog = new DirectoryCatalog(".\Plugins") which will take the plugins folder off of your bin.

You also don't have to use the batch directly. Instead we've added a convenience extension method on the container called ComposeParts which lives in System.ComponentModel.Composition.

With it you can change the code above to just....

_container.ComposeParts(this) ;

thus consolidating the 3 lines of non-intuitive code to one. It accepts a params arrray as well so you can pass multiple parts.

Glenn

Peter O'Hanlon

unread,
Dec 20, 2009, 9:46:36 AM12/20/09
to wpf-di...@googlegroups.com
Glenn
 
Cool. Thanks for that. The only real problem I have with MEF right now is that the documentation is a bit sparse, and light on best practice guidance. I guess that's natural at the moment, but it can make figuring things out a bit of a pain.

--
Peter O'Hanlon

Laurent Bugnion, GalaSoft

unread,
Dec 20, 2009, 9:58:50 AM12/20/09
to wpf-di...@googlegroups.com

Who needs documentation when you can have Glenn’s personal MSN account (I will send you his contact info against a small payment ;))

 

Just kidding. I agree that lack of doc needs to be solved to see a wide adoption. Hope the team has some time for that soon J

 

Laurent

 

From: wpf-di...@googlegroups.com [mailto:wpf-di...@googlegroups.com] On Behalf Of Peter O'Hanlon
Sent: Sunday, December 20, 2009 3:47 PM
To: wpf-di...@googlegroups.com
Subject: Re: [WPF Disciples] MEF

 

Glenn

Peter O'Hanlon

unread,
Dec 20, 2009, 4:08:27 PM12/20/09
to wpf-di...@googlegroups.com
I shall make payment when your new SL4 comes out. I have high hopes after your last book.
--
Peter O'Hanlon

Sacha Barber

unread,
Dec 21, 2009, 4:11:18 AM12/21/09
to wpf-di...@googlegroups.com
You haz succeeded (LOL talk, I haz it, http://icanhascheezburger.com/)
 
MEF is cool....well done

--
Sacha Barber
sacha....@gmail.com

Peter O'Hanlon

unread,
Dec 21, 2009, 4:12:55 AM12/21/09
to wpf-di...@googlegroups.com
U haz codz skillz...
--
Peter O'Hanlon

Sacha Barber

unread,
Dec 21, 2009, 4:16:01 AM12/21/09
to wpf-di...@googlegroups.com
--
Sacha Barber
sacha....@gmail.com

Glenn Block

unread,
Dec 21, 2009, 5:04:20 AM12/21/09
to wpf-di...@googlegroups.com
We know. We've got much better docs in the works which will shop in MSDN. On the topic of best practices, I am starting to cover some of that in my new series on my blog. It's focused on Silverlight, but many of the practices are the same.

Glenn Block

unread,
Dec 21, 2009, 5:05:14 AM12/21/09
to wpf-di...@googlegroups.com
As long as I get a decent cut I am ok with that :-)

Sacha Barber

unread,
Dec 21, 2009, 5:13:23 AM12/21/09
to wpf-di...@googlegroups.com
This is what I tend to do
 
 
public MainWindow()
{

    App.ComposeMEFContainer(this);
}
 
 
public static void ComposeMEFContainer(Object part)
{
    var directory = System.IO.Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
    var container = new CompositionContainer(new DirectoryCatalog(directory));
    var batch = new CompositionBatch();
    batch.AddPart(part);
    container.Compose(batch);
}
 
 
Glenn, how could you make this better, its the same as what Peter is trying to do I think, where we have  have a Plugins folder somewhere. Except for me this was just the bin folder of my app.
--
Sacha Barber
sacha....@gmail.com

Glenn Block

unread,
Dec 21, 2009, 5:16:34 AM12/21/09
to wpf-di...@googlegroups.com
Add a "using System.ComponentModel.Composition" in the class.
 
public static void ComposeMEFContainer(Object part)
{
    var container = new CompositionContainer(new DirectoryCatalog(@".\"));
    container.ComposeParts(part);
}
 
Should work.....

Why use a static class? Are you calling it multiple times in the app?

Sacha Barber

unread,
Dec 21, 2009, 5:18:33 AM12/21/09
to wpf-di...@googlegroups.com
Cool.
 
No it only gets called once actually, good point, can change from static. Cheers Glenn.

--
Sacha Barber
sacha....@gmail.com

Glenn Block

unread,
Dec 21, 2009, 5:20:32 AM12/21/09
to wpf-di...@googlegroups.com
Yeah, a common pattern is to make the method parameterless (you might not even need a method for two lines :-) ), and just call container.ComposeParts(this)

Glenn Block

unread,
Dec 21, 2009, 5:23:20 AM12/21/09
to wpf-di...@googlegroups.com
Cheers Sacha, off to bed.

Corrado Cavalli

unread,
Dec 21, 2009, 5:37:21 AM12/21/09
to wpf-di...@googlegroups.com
Your blog series is a invaluable source of resources about MEF,
I've learned more from them than Codeplex wiki and MSDN, keep
going! ;-)

-Corrado


On Mon Dec 21 04:04:20 CST 2009, Glenn Block

Sacha Barber

unread,
Dec 21, 2009, 6:11:45 AM12/21/09
to wpf-di...@googlegroups.com
NIght night.
--
Sacha Barber
sacha....@gmail.com
Reply all
Reply to author
Forward
0 new messages