One MEF to rule them all (Part 1)

2009/10/04

no comments

This post is the first of short series which will cover the task of creating simple Rule Engine using MEF technology.

from technical perspective the series will talk about the following techniques:

  • Filtering MEF results using custom catalog
  • Exporting both classes and methods
  • Using metadata

the post code is available for download here

Prerequisite

this post assume basic understanding of the MEF technology (for MEF introduction read this post)

 

Part 1

part 1 will focus on filtering MEF results using custom catalog

Filtering MEF results

MEF architecture is using catalogs (ComposablePartCatalog) to discover MEF parts.

the catalogs responsibility is to locate the parts using specific strategy.

The idea behind the filter Catalog

the filter catalog will act as wrapper for other catalogs (this way it is not restricted for specific discovery strategy).

the relation between the filter catalog to the concrete catalog resemble the relation between BufferedStream and the concrete stream,

the concrete catalog is responsible for the discovery and the filter catalog is responsible for filtering.

Analyzing the filter catalog code

The heart of the catalog filtering using Where clause (LINQ) on the inner catalog’s Parts.

The filter catalog override 2 methods

  • Parts: redirect to the inner catalog parts
  • GetExports: filter the export definitions

public class FilteredComposablePartCatalog : ComposablePartCatalog {
// the inner catalog parts
private readonly IQueryable<ComposablePartDefinition> _parts;
// the current filter
private Predicate<ExportDefinition> _exportDefFilter;
public FilteredComposablePartCatalog(ComposablePartCatalog catalog,
Predicate<ExportDefinition> exportDefFilter) {
_parts = catalog.Parts;
_exportDefFilter = exportDefFilter;
} public override IQueryable<ComposablePartDefinition> Parts {
get { return _parts; } // redirect to the inner catalog parts
} // filter the export definitions
public override IEnumerable<Tuple<ComposablePartDefinition, ExportDefinition>>
GetExports(ImportDefinition definition) {
var exports = from expDefTuple in base.GetExports(definition)
let expDef = expDefTuple.Item2
where _exportDefFilter(expDef)
select expDefTuple;
return exports;
}
}

Using the filtered catalog

for usability purpose i added extension method called AssignFilter

var dirCatalog = new DirectoryCatalog (PLUG_INS_FOLDER);
var catalogFiltered = dirCatalog.AssignFilter(
    expDef => (bool)expDef.Metadata["CustomMetadata"] == true);

so as a consumer the experience is quite similar to adding any other catalog.

the filter catalog hide the filtering implementation and all we have to do is to supply predicate.  

Solution structure

The solution structure contain the following projects:

  • MefRuleEngine.Common (contain contracts, attributes, enums and helpers)
  • FilteredComposablePartCatalog (the code of the filter catalog)
  • MefRuleEngine.Plugins.DebugEnvironment (rules implementation for debug environment)
  • MefRuleEngine.Plugins.ProductionEnvironment (rules implementation for production environment)
  • ComponentModel.Initialization (will be part of MEF in the future)

 

Summary

in this part of the series we discuss the filtering technique,

the following parts will focus on using metadata and adding export attribute on methods.

we will also speak about the current implementation of the rules engine and on how to visualize simulation for specific inputs.

 

The post code is available for download here

 

Shout it kick it on DotNetKicks.com


Add comment
facebook linkedin twitter email

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*