Export Providers and Custom factories with MEF
Matt Hawley has a nice set of posts where he explores a method to extend MEF to allow custom activated exports.
scenario involves exporting a set of WCF proxies. WCF proxies can’t
simply be instantiated through the constructor, so he needed a way to
control the activation. One thing he could have done is manually create
the instances and use the AddExportedObject method on the container to
add them directly. This would mean however that the container wasn’t
doing the work. Another option is using property exports, as they allow
you to control
the creation logic in the property getter. The down side of this
approach is needing to have a separate
property for each service. So what to do? Utilize MEF’s extensibility
points. MEF has several points which can use to extend it’s behavior,
one is catalogs, another is using Export Providers.
Matt first headed down the custom catalog route. He created a catalog (by inheriting from ComposablePartCatalog)
that inspects a set of assemblies for types
with a marker interface which is passed in at the constructor. That
catalog also accepts a custom func as a parameter that is used for
activating the parts it holds which in this case was the WCF proxy
activation logic. Next he created a custom part and custom part
(catalogs return Part Definitions, and Part Definitions create Parts)
which both carried only one export which was the service. The solution
required a bunch of work and several classes. Creating these classes is
what we in MEF land call a custom programming model (custom part + part
definition). The advantage of creating a custom model is you can
have imports on your custom parts composed by the container. In this
case, Matt did not need any imports, so in his implementation he set
the imports collection to always be empty. The solution worked, but was
not optimal. A new programming model was being created simply to carry
a custom export, while the rest of the model would be essentially
In our new bits, there’s one more way to skin this cat using a class known as ExportProvider, which is the second approach Matt used.
Export Providers are really flexible in that they provide a simple way
for you to hook in your own custom resolving logic into the container.
Export Providers do what the name describes, they provide exports.
Exports are a lazy instantiated handle to an instance of an export. The
instance that the Export points to gets instantiated when its
GetExportedObject method is called, which either happens during
composition, or in a delayed manner if it is a lazy export
(Export<T>). It turns out that an Export contains a factory
method (func) which is called by the GetExportedObject method. In this
case it is being used for instantiating a WCF proxy and is thus
allowing MEF to interoperate with non-MEF components. However, you could use
them for other means like talking to a legacy system, establishing a
set of default exports (like a default logger), or to filter (apply policy) to other Export Providers.
talk more about creating custom providers in a future post but I advise
you to check out Matt’s set of posts as a great way to get started
understanding the possibilities.