MEF vs. any IoC
Asked Answered
C

4

72

Looking at Microsoft's Managed Extensibility Framework (MEF) and various IoC containers (such as Unity), I am failing to see when to use one type of solution over the other. More specifically, it seems like MEF handles most IoC type patterns and that an IoC container like Unity would not be as necessary.

Ideally, I would like to see a good use case where an IoC container would be used instead of, or in addition to, MEF.

Collectivize answered 17/8, 2009 at 14:47 Comment(1)
Related question hereVictualler
M
77

When boiled down, the main difference is that IoC containers are generally most useful with static dependencies (known at compile-time), and MEF is generally most useful with dynamic dependencies (known only at run-time).

As such, they are both composition engines, but the emphasis is very different for each pattern. Design decisions thus vary wildly, as MEF is optimized around discovery of unknown parts, rather than registrations of known parts.

Think about it this way: if you are developing your entire application, an IoC container is probably best. If you are writing for extensibility, such that 3rd-party developers will be extending your system, MEF is probably best.

Also, the article in @Pavel Nikolov's answer provides some great direction (it is written by Glenn Block, MEF's program manager).

Melissiamelita answered 20/8, 2009 at 0:48 Comment(5)
This MSDN article really drove the point home for me: msdn.microsoft.com/en-us/library/hh708870.aspx. To a MEF newcomer familiar with IoC/ID, MEF appears to be injection (composition)...without the type registrations. So, the above SO answer really drives the point home for me. Listening right now to the much-touted Hanselman podcast episode on the topic: hanselminutes.com/148/…Zaporozhye
Please point out some specific examples where any IoC would be more useful with static dependencies (known at compile-time) than MEF. I find the Export\Import Attributes or Registration Builder much more useful for static dependencies than complicated error prone config files.Disenfranchise
@AaronStainback: My container of choice is Autofac, which prefers code-based registration over configuration files, similar to Registration Builder (I do not like XML). Advantages of Autofac over MEF include: registration via lambda expressions, fine-grained lifetime control, and composition ignorance (composed types need know nothing of Autofac or the context in which they are used). Those aspects are most advantageous when you control the composed types, hence the differences in emphasis between Autofac and MEF. The Venn diagram between the two generally covers simpler DI scenarios.Melissiamelita
@AaronStainback: Also, please reserve downvotes for incorrect or misleading answers, rather than to reflect personal preference. Lack of an upvote communicates that.Melissiamelita
@BryanWatts: the downvote was not for a personal preference it was for having a subjective answer without giving any facts. The items you point out in your reply would have been great knowledge to have in your answer although they are not 100% accurate. MEF 2.0 in .NET 4.5 has composition ignorance so I would not consider that a advantage. Also MEF has registration via lambda expressions as well, so that one is a tie as well. MEF also added some more fine grained lifetime management in .NET 4.5. Autofac has more built in lifetime strategies but MEF give the tools to build them.Disenfranchise
F
28

I've been using MEF for a while and the key factor for when we use it instead of IOC products is that we regularly have 3-5 implementations of a given interface sitting in our plugins directory at a given time. Which one of those implementations should be used is actually something that can only be decided at runtime.

MEF is good at letting you do just that. Typically, IOC is geared toward making sure you could swap out, for a cononical example, an IUserRepository based on ORM Product 1 for ORM Product 2 at some point in the future. However, most IOC solutions assume that there will only be one IUserRepository in effect at a given time.

If, however, you need to choose one based on the input data for a given page request, IOC containers are typically at a loss.

As an example, we do our permission checking and our validation via MEF plugins for a big web app I've been working on for a while. Using MEF, we can look at when the record's CreatedOn date and go digging for the validation plugin that was actually in effect when the record was created and run the record BOTH through that plugin AND the validator that's currently in effect and compare the record's validity over time.

This kind of power also lets us define fallthrough overrides for plugins. The apps I'm working on are actually the same codebase deployed for 30+ implementations. So, we've typically go looking for plugins by asking for:

  1. An interface implementation that is specific to the current site and the specific record type in question.
  2. An interface implementation that is specific to the current site, but works with any kind of record.
  3. An interface that works for any site and any record.

That lets us bundle a set of default plugins that will kick in, but only if that specific implementation doesn't override it with customer specific rules.

IOC is a great technology, but really seems to be more about making it easy to code to interfaces instead of concrete implementations. However, swapping those implementations out is more of a project shift kind of event in IOC. In MEF, you take the flexibility of interfaces and concrete implementations and make it a runtime decision between many available options.

Fenrir answered 10/9, 2011 at 20:14 Comment(1)
I like the example of applying multiple validations via MEF.Roughandready
T
5

I am apologizing for being off-topic. I simply wanted to say that there are 2 flaws that render MEF an unnecessary complication:

  • it is attribute based which doesn't do any good to helping you figuring out why things work as they do. There's no way to get to the details burred in the internals of the framework to see what exactly is going on there. There is no way to get a tracing log or hook up to the resolving mechanisms and handle unresolved situations manually

  • it doesn't have any troubleshooting mechanism to figure out the reasons for why some parts get rejected. Despite pointing at a failing part it doesn't tell you why that part has failed.

So I am very disappointed with it. I spent too much time fighting windmills trying to bootstrap a few classes instead of working on the real problems. I convinced there is nothing better than the old-school dependency injection technique when you have full control over what is created, when, and can trace anything in the VS debugger. I wish somebody who advocates MEF presented a bunch of good reasons as to why would I choose it over plain DI.

Tequilater answered 19/11, 2012 at 20:2 Comment(0)
S
1

I agree that MEF can be a fully capable IoC framework. In fact I'm writing an application right now based on using MEF for both extensibility and IoC. I took the generic parts of it and made it into a "framework" and open sourced it as its own framework called SoapBox Core in case people want to see how it works.

In particular, take a look at how the Host works if you want to see MEF in action.

Speculum answered 7/11, 2009 at 3:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.