MEF for Beginner (repeatable metadata) – part 9
this post will focus on having repeatable metadata definition (cases like definition of multiple categories).
if you not familiar with the MEF metadata concept you may want to read part 8.
Bad practice for repeatable metadata
In order to explain repeatable metadata, we will start by decorating export with
untyped metadata declaration (which consider as bad practice, use typed metadata
whenever you can, it is mach usable and reducing runtime failure).
the above code snippet decorate the plug-in with categories metadata for both Travel and City (line 3,4).
notice that we should explicitly declare that those decoration is multiple (IsMultiple=true).
line 1: define the export.
latter on this post we will see the best practice of declaring the metadata using custom attribute.
Metadata view contract for repeatable metadata definition
the metadata view contract properties type, for repeatable metadata decoration, should be Array, or IEnumerable.
the following metadata view contract is capable to handle the above metadata decoration:
as you can see, line 3, define property that match the name of our metadata decoration (Categories)
and it is using array for its data type.
Best practice for metadata definition
as in the previous part, the best practice for metadata definition is
using typed metadata, which mean to define attribute for the metadata.
as you can see it is almost identical for the definition of non-repeatable metadata attribute,
but with 2 differences:
- we should declare that the attribute allow multiple occurrence (at the end of line 2),
this definition is equivalent to the IsMultiple definition on the untyped metadata.
- we should derive from Attribute (instead of ExportAttribute, otherwise we will get multiple
instantiation of our plug-in).
the plug-in decoration will look as follow:
in term of code safety typed metadata leaving less margin for errors,
and it is match more usable because it is easier to understand which value are expected.
The Import decoration
our import should use the Lazy<IPlug, IMetadataView> in order to get the metadata information
(through the IMetadataView contract ).
Interrogating the metadata
the following code will compose and interrogate the metadata.
lines 6-8, is handling the composition.
line 10, iterating for each of the discovered plug-in.
line 13, iterating for each of the items in the metadata categories property upon specific plug-in.
having multiple metadata on the same export is slightly more challenging.
the main difference between working with repeatable metadata relate to the metadata decoration (AllowMultiple=true)
and having Array or IEnumerable at the metadata view properties level.
Download the code
full project download for the post sample and for WPF sample that using this post concept for
Point of interest
- do not use setter on your metadata view interface.
- do not use the [InheritedExport] because for some some strange reason it doesn’t functioning well along with metadata.
- if you want to build advance metadata view contract you can use class instead of interface,
but that class must have constructor with the following signature:
public ClassName (IDictionary<string, object> metadata)
inside the constructor you should map the metadata dictionary to the class properties.