Saturday, May 1, 2010

MEF: DLL Versions and Multiple Exports for a Class

During my talk about the Managed Extensibility Framework (MEF) at Devscovery this past week, I had two very good questions asked by the audience and promised I'd get an answer.

The first one was about exporting in MEF. I was under the impression that a MEF part could have one export, but I was mistaken. The confusion came from this thread which doesn't question multiple exports, but rather the shared policy (whether there is one export, or multiple instances of an export created). It's one of those cases where I had read that and somehow got it in my head it wasn't supported, and then simply didn't have a reason to need it so I never investigated it further.

So, thanks for the great question.

Answer One: you can export a single class under multiple interfaces. Not a problem. And, depending on your creation policy, you can ensure only one instance is exported, or a separate interface for the different contracts.

The second one was a little more interesting. It was about versioning and DLLs. The question was if I import an assembly that has a part, then update the assembly on disk, can I pull in the new version?

Answer Two: no, you cannot reload a newer version of the assembly when it is updated on disk This isn't a MEF limitation, but part of the CLR itself. If you think about it, you cannot do this without MEF, either. You might overwrite the DLL, but it will not get loaded (if it already is loaded) until you restart the application. Technically, you can unload the entire app domain or launch a new app domain, but you cannot unload the assembly within an app domain.

Wintellect's Jeffrey Richter explains it well in this dot net rocks interview (PDF transcript). He says:

No you cannot and we will probably never offer that feature. If you think about it, if you load an assembly into an app domain and then you start executing code in that assembly, that may cause other assemblies to get loaded into that app domain as well. And then if you unloaded the first one, we don't know to unload all the others that got loaded accidentally, if you will. So that is one of the reasons why we have app domains, is so that you can do this unloading and then all the other assemblies that got loaded as a side effect get unloaded at the same time. And we are probably going to keep that. We have heard that request from many people that if they want to unload an assembly, may be some day we'll add it, but I think it's very unlikely.

Thanks to everyone who attended and hope this answers your questions.

Jeremy Likness