I need to add some extension points to our existing code, and I've been looking at MEF as a possible solution. We have an IRandomNumberGenerator interface, with a default implementation (ConcreteRNG) that we would like to be swappable. This sounds like an ideal scenario for MEF, but I've been having problems with the way we instantiate the random number generators. Our current code looks like:
public class Consumer
{
private List<IRandomNumberGenerator> generators;
private List<double> seeds;
public Consumer()
{
generators = new List<IRandomNumberGenerator>();
seeds = new List<double>(new[] {1.0, 2.0, 3.0});
foreach(var seed in seeds)
{
generators.Add(new ConcreteRNG(seed));
}
}
}
In other words, the consumer is responsible for instantiating the RNGs it needs, including providing the seed that each instance requires.
What I'd like to do is to have the concrete RNG implementation discovered and instantiated by MEF (using the DirectoryCatalog). I'm not sure how to achieve this. I could expose a Generators property and mark it as an [Import], but how do I provide the required seeds?
Is there some other approach I am missing?
The Managed Extensibility Framework or MEF is a library for creating lightweight, and extensible applications. It allows application developers to discover and use extensions with no configuration required. It also lets extension developers easily encapsulate code and avoid fragile hard dependencies.
For those who don't know, the Managed Extensibility Framework (MEF) is alive and well, and has been ported to . NET Core as System. Composition (source here).
Managed Extensibility Framework (MEF) is a component of . NET Framework 4.0 aiming to create lightweight, extensible applications. It aims to allow . NET application developers to discover and use extensions with no configuration required.
Overview of the Managed Extensibility Framework. The MEF is a . NET library that lets you add and modify features of an application or component that follows the MEF programming model. The Visual Studio editor can both provide and consume MEF component parts.
Currently there isn't a direct way to do this in MEF but the MEF team is considering support for this in v.Next. You essentially want to create multiple instances of the same implementation which is traditially done using a Factory pattern. So one approach you could use is something like:
public interface IRandomNumberGeneratorFactory
{
IRandomNumberGenerator CreateGenerator(int seed);
}
[Export(typeof(IRandomNumberGeneratorFactory))]
public class ConcreateRNGFactory : IRandomNumberGeneratorFactory
{
public IRandomNumberGenerator CreateGenerator(int seed)
{
return new ConcreateRNG(seed);
}
}
public class Consumer
{
[Import(typeof(IRandomNumberGeneratorFactory))]
private IRandomNumberGeneratorFactory generatorFactory;
private List<IRandomNumberGenerator> generators;
private List<double> seeds;
public Consumer()
{
generators = new List<IRandomNumberGenerator>();
seeds = new List<double>(new[] {1.0, 2.0, 3.0});
foreach(var seed in seeds)
{
generators.Add(generatorFactory.CreateGenerator(seed));
}
}
}
MEF preview 8 has experimental support for this, though it is not yet included in System.ComponentModel.Composition.dll
. See this blog post for more information.
You'll have to download the MEF sources and build the solution. In the Samples\DynamicInstantiation
folder you'll find the assembly Microsoft.ComponentModel.Composition.DynamicInstantiation.dll
. Add a reference to this assembly and add a dynamic instantiation provider to your container like this:
var catalog = new DirectoryCatalog(".");
var dynamicInstantiationProvider = new DynamicInstantiationProvider();
var container = new CompositionContainer(catalog, dynamicInstantiationProvider);
dynamicInstantiationProvider.SourceProvider = container;
Now your parts will be able to import a PartCreator<Foo>
if they need to dynamically create Foo
parts. The advantage over writing your own factory class is that this will transparently take care of the imports of Foo
, and the imports' imports, etcetera.
edit:
PartCreator
was renamed to ExportFactory
but it is only included in the silverlight edition.ExportFactory
became included for the desktop edition. So ExportFactory
will probably be part of the next .NET framework version after .NET 4.0.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With