MEF + MAF Guidance? (How do they integrate with each other)

Jan 9, 2009 at 4:07 PM
Edited Jan 9, 2009 at 4:10 PM
What is the thinking on MEF/MAF and how could MEF leverage MAF? I like the recomposition in MEF, but it seems really limited without leveraging MAF's ability to seperate things out into different App Domains.

So is the solution to extend MEF with a PartCatalog and builder to use MAF? Is this being worked on, or being left up to the end-developer to do?
Jan 9, 2009 at 7:01 PM
Hi @jblosser

Thanks for the feedback. MEF and MAF were built do address two different problems. MAF is as you observed a solid story for versioning and isolation. MEF on the other hand is built to be a light composition model (light in the sense that it doesn't impose a lot on the objects it composes, and that is uses a  simple declarative model)

In terms of getting the two technologies to work together this is something we believe is possible. MEF at it's core is not specific about activation, the parts themselves define the activation model. We're planning to deliver a sample that illustrates how this is done. The way we are planning to approach it is through a custom programming model which would include custom part definitions / parts and a catalog. The sample should be out in a few months.

Thanks
Glenn

Feb 12, 2009 at 4:22 PM
Hi Glen,

any ETA on the MEF / MAF sample?

We've been using MEF (and CompositeWPF) on an internal project and have had a lot of sucess with it and are about to embark on a new tool that requires an add-in framework and I'm set on using MAF, but I'd like to know how we can integrate the two.

Any guidance would be massively appreciated.

Many thanks,

Howard van Rooijen
Feb 12, 2009 at 7:08 PM
Not yet, though I plan to get something out there in the next month. It's a plan, so I am not promising ;-)

In terms of using MEF / Prism experience, that sounds great, we are starting to see a lot of folks coming out of the woodwork doing that. I've been chatting with p&p guys about more proper support, and I am confident it's coming.

Would love to hear more about your scenarios though. Shoot me an email at gblock@microsoft.com if you want to chat.

Regards
Glenn
Feb 13, 2009 at 7:05 PM
Do you really think this will be workable?  I'm extremely skeptical...

I started trying to use MAF for composable applications and gave up - there's simply too much overhead involved in manually writing adapter classes, and the pipeline builder tool has no real support (that I could see) for inheritance hierarchies between contracts and makes casting between contracts too difficult; the sort of things you're highly likely to want for composable applications.  So, you end up having to write (huge) amounts of adapter code.

Personally, I can't help but think that MAF is doomed to limited use - it introduces too much complexity for the sake of versioning, making you pay this price irrespective of whether you need to adapt contract interfaces.  Maybe there are technical reasons for this, but superficially at least, I don't get why it wouldn't instead have been possible to have components interface directly with contract interfaces, and inject adapter proxy classes only when/if needed.  I guess maybe it's related to resource management of addins between appdomains.

Just seems that unless this adapter infrastructure can be hidden, (IMO) it's never going to be used for composable apps.

If you guys can actually find some way to consolidate the two system without creating an ugly monster I'll be extremely impressed.

There are a couple of ideas from MAF though which I think are good, and which could be added to MEF - the main one being transitive closure of contracts.  I'd rather see addition of this and a binary packaging model for addins than creation of a MEF-MAF monster.

If you could add these features (in order of importance):
- binary packaging and distribution model (handle installation, conflict resolution between contract assemblys - must be strongly named, must have same content hash)
- ability to enforce and identify transitive closure of contracts (plus enforce strong naming etc.)
- AppDomain isolation to allow safe use of weakly named assemblies (though contract assemblys must be strongly named).
- transparent injection of contract interface adapter proxies (for version adaptation)

I'd personally be in composable application nirvana :)

Regards,
Phil

Feb 13, 2009 at 8:30 PM
I do think it's technically possible to get the two to integrate (as I've done this), though I am not saying that it will make working with MAF any easier ;-) Our goal is simply to explore the integration and map out how one could do it.

Addressing the problem lives on a conitnuum from pretty simple solutions, to much more complex and less straightforward ones.

Here's the high level thinking of possibilities.

1. Importing MAF exports as black boxes. This means that you have MEF attributed parts that import from MAF. MEF doesn't known anything about those parts other than they implement a contract. There are several options on how we can do this. The upside of this approach is it is pretty simple, and pretty straight forward. The downside of ths approach is that MAF parts themselves are not being composed with their own imports.

In terms of whether or not this is useful. I would see it for an App that uses MEF's attributed parts model to compose it's trusted components that do not need to live in an isolation boundary / get unloaded, while it uses MAF to import in 3rd-party untrusted code.

2. Composing MAF parts with imports coming from the container.

This has two aspects:

  a. Locally composing MAF parts such that their dependencies all live in the same app domain. This could possibly be done by having the MAF part spin up it's own container which it uses to locally compose it's components (including itself). I have questions on whether or not this would be useful.
  b. Composing MAF parts with imports that may come from across the app domain boundary. This would likely require a signficant amt of infrastructure work:
  • MEF allows defining custom parts / part models (we call these programming models), so conceptually one could be defined that uses MAF for activation. This would mean you could have a MAF catalog that discovers MAF parts, etc. It would also be quite a bit of work
  • Another possibility what would not involve creating a new model, would be decorating the MAF client view with export attributes so it essentailly becomes a part. Once it's an attributed part, we can satisfy it's imports, even though it was instantiated through MAF.

The real challenge is around getting imports across the wire. MAF has specific restrictions that will get imposed on any exports that would get imported by those MAF components. If you tried to import something that was not properly designed to be passed (i.e. did not have the appropriate MAF infrastucture in place for it), the composition will fail. This means that a lot of MAF stuff will bleed into your pure and simple MEF part world.

So in short, importing MAF components as black boxes seems entirely achievable, composing MAF components on the other hand is much more work and less clear cut.

Regards
Glenn





Feb 13, 2009 at 10:53 PM
In a way I guess that's kind of my point - the workable option (#1) doesn't seem to get you much - you end up with either some infrastructure code or a design pattern that imports MAF client side adapters ( I assume that's what you're indicating ).  And, I kind of wonder ... can't I already do that myself, maybe with a bit of manual work, but you end up with a portion of the system which doesn't handle open-ended composability - for that part of the system you're back to a situation where only one level of extensibility is practical.

I just wonder if it might be possible to add some of the capabilities of MAF to MEF (without using MAF) and 'have your cake and eat it too' ;)

Personally, I'm developing a MEF based system which handles some of the addin binary packaging and deployment issues which MEF itself doesn't handle.  I'm achieving this via enforcement of strong naming and hashing of assembly file contents to ensure unique, consistent assembly identity.  I currently have to do this for all assemblies, not just contract assemblies since there's currently no support for AppDomains.

I keep on wondering to myself, whether maybe I should look into adding support for AppDomains, and how hard this would be.  If achievable it would seem a much nicer option than combining MEF and MAF, and you'd get most of the advantages of MAF without (hopefully) losing the composability or simplicity of MEF.  Of course, I'm probably way underestimating how much work it would be to do this.

Anyway, sorry for the ramble; I will be very interested to see whatever you guys come up with.

Regards,
Phil

Feb 13, 2009 at 11:15 PM
Edited Feb 13, 2009 at 11:21 PM
Thanks Phil. I agree that 1 does not buy you as much, though it does buy you the chance to reuse your MAF components. The benefit is that the non-MAF portion of your app can be composed through MEF, and utilize those MAF components within them.

In terms of bringing in support for the types of problems that MAF addresses namely versioning and isolation, this will be something we will be looking into for vNext i.e. post .NET 4.0. It's not something we have the bandwidth to take on before we ship.

Feb 25, 2009 at 7:40 PM
Guys, Kent Boogaart just did a nice post on using MEF and MAF together. Basically he is doing what I described above in option 2a, Composing locally within a MAF addin.

http://kentb.blogspot.com/2009/02/maf-and-mef.html

Apr 7, 2009 at 9:35 PM

On Feb 12 at 11:08 AM gblock wrote:

Not yet, though I plan to get something out there in the next month. It's a plan, so I am not promising ;-)

 

Any update on this?

I'd like to echo much of what pspidey has written  -- MAF looks good, but there's too much complexity.

In terms of MEF+MAF features, what I'm looking for is:
  • support for add-in and host versioning similar to MAF (although if we could simplify it without giving up too much of the flexibility, that would be great).
  • a mechanism for add-ins to use interfaces provided by other add-ins (with version adapters).*separate app-domains for each add-in. In out situation, this isn't for in-house vs. 3rd party isolation, but rather to prevent poorly written add-ins (admittedly, written in-house) from taking down an entire windows service.

I think, this boils down to Glenn's option 2b.

(*Slight digression: Ideally, the add-in to add-in version wouldn't be constrained by the add-in to host version. That is: I release host.v1, addInA.v1, and addInB.v1, then a second release of all three, but only install addInA.v2 and addInB.v2 on the workstation. My communications from addinA to host to go through the AddInAV2ToV1 adapter, which will cause V2 funcitonality to be ignored/simulated/errored/etc. Same with addInB.v2. Ideally when addInB.v2 talks to addinA.v2, they should be able to do so using V2 interfaces, rather than squeeze communication down to V1.)

Thanks.