Coffeehouse Thread

12 posts

Using MEF for the first time : any words of experience?

Back to Forum: Coffeehouse
  • Dr Herbie

    We're having to add 'enterprisey' integration to our application so I've gone for MEF as a plug-in container.  We're both retrieving external data and running commands into external systems (for example, we retrieving costs from a system and also raising purchase order requests).

    I've gone for a Directory catalogue (with a file-watcher so we can have live updates when new DLLs are dropped into place).

    Plug-In interfaces and DTO definitions are defined in their own project for the plug-ins to reference, so I feel we have pretty good separation from the main application.

    Anyone got any war-stories regarding MEF? Anything going to catch me out?

    Note: we're .NET 3.5, so I got MEF from Codeplex and recompiled with a strong name.

     

    Herbie

  • Deactivated User

    Comment removed at user's request.

  • Dr Herbie

    @bystander: Thanks, I hadn't though of broken extensions breaking then whole composition.

    Herbie

  • aL_

    Im actually using mef for a large:ish project at work and i find it really addicting actually, its really handy to just import what ever instances i need in a perticular class and not have to worry about how they actually get there.

    I've also gone the route of having a 'Core' assembly for all the models and interfaces and lots of other assemblies whith actual implementations.

    I've also found generic mef contracts to be very useful, my app is an mvvm app and all the views implement an interface IView<TViewModel> where TViewModel is the type of the viewmodel the view is supposed to present.

    I then have a property in my main viewmodel of type Object that represent the active view(model), and when i set that to a viewmodel a custom value converter that looks for the appropriate IView<TViewModel> in mef.

    Perhaps it sounds a little complicated but its quite nice, because viewmodels are never aware of the actual view, even when they get displayed in the ui, the View <-> Viewmodel resolution is done by mef via the custom value converter, and its just 10 lines of code (even though one is kinda long):

        public object Convert( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture ) {
          if( value != null && Container != null ) {
            var type = typeof( IView<> ).MakeGenericType( value.GetType( ) );
            var view = ( Control )Container.GetExports( new ContractBasedImportDefinition( AttributedModelServices.GetContractName( type ), AttributedModelServices.GetTypeIdentity( type ), null, ImportCardinality.ExactlyOne, false, false, CreationPolicy.Any ) ).First( ).Value;
            view.DataContext = value;
            return view;
          }
          else
            return null;
        }

     

    There are some stuff that will get me from time to time, not huge issues but something to be aware of. Mef employs what they call stable composition, this means that if a part A has a dependency (via an import) on another part B, and there is not available instance of B, then mef wont include any instances of A in the composition either.

    This actually makes a lot of sense, but no error is thrown when this happens, but mef instead prints a warning to the output window. If some of your ImportMany properties are inexplicably empty, then this might be happening.

    Another thing to be aware of is that contract types are not checked at compile time, its perfectly fine to export a class as IFoo, without actually implementing IFoo on the class it self. Contract names are really just strings and you can indeed use strings as contract names.

    Mef will throw an error at runtime if it turns out it could not assign an instance of the export to a perticular import because of conflicting types.

  • PerfectPhase

    Don't forget that you've just given people a way to run random code in your process, so if this is a private extension point for you then check public key signatures when loading, if you don't trust the people writing the extensions take steps to protect yourself.

  • Deactivated User

    Comment removed at user's request.

  • aL_

    @bystander:

    you can also defer loading to another thread, what i do is load the initial app and display the main window, then i do the part discovery on another thread, and when that's done i do the actual composition (.Compose()) on the main thread.

    You could also do your own version of Directory catalog, all it really does internally is load each assembly and create an Assembly catalog from that.

    in my app o solved it by having a special folder for plugins and also doing the assembly loading on a background thread

  • Deactivated User

    Comment removed at user's request.

  • Harlequin

    Is PRISM an okay thing to use, or is it for larger projects? Think it has MEF stuff built in if I remeber from reading about it a while ago.

  • Bass

    Adding "enterprisey" features to an app for the sake of being more "enterprisey" is a recipe for epic fail.

    Ask yourself if you have a use case for MEF, something that directly impacts end users. It's not for every app.


    Do you see this as something your customers could take advantage of (ie, extending your software in the form of plugins)? Another use case is for very large apps that can download parts of themselves on demand.



  • Dr Herbie

    We're adding 'enterprisey' features because our customers need them (interfacing to accounting and purchase order systems). It's not just for the sake of it.

    We have a very vertical market and a small number of clients: some of our clients have customisations they want to allow our system to integrate with other systems, or to handle business logic that is unique to them.  Using MEF will allow us to have customer-specific portions of code that only get installed for the specific customer who commissions them -- it's like a 'semi-bespoke' system.  We won't be opening up for third parties to add extensions, we will be coding it all.

    Herbie

  • Magnifico

    I recently gave a code camp talk that highlights a few gotchas and wrote a blog entry to accompany.  Includes a video and some ideas on testing composition.  Check it out!

    https://ihadthisideaonce.wordpress.com/2012/01/31/stop-guessing-about-mef-composition-and-start-testing/

Comments closed

Comments have been closed since this content was published more than 30 days ago, but if you'd like to continue the conversation, please create a new thread in our Forums, or Contact Us and let us know.