UPDATE: Should I try to process it with a DI container or is this the wrong level of abstraction here?
I would like to implement ABSTRACT FACTORY using MEF (.NET 4.5).
This does not work for me ...
The composition remains unchanged. Changes were rejected due to the following errors (errors):
The composition produced a single compositional error. The main reason is given below. See the CompositionException.Errors property for more information.
1) Export not found, which corresponds to the restriction:
ContractName Mef3.Factory
RequiredTypeIdentity Mef3.Factory Result: Unable to set import "Mef3.Program._factory (ContractName =" Mef3.Factory ")" to the part "Mef3.Program".
Element: Mef3.Program._factory (ContractName = "Mef3.Factory") → Mef3.Program
Is this the right way to do this in MEF? How can I forward id to Foo / Bar ctors?
The code:
class Program
{
static void Main(string[] args)
{
var program = new Program();
program.Run();
}
readonly CompositionContainer _container;
public Program()
{
var catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
_container = new CompositionContainer(catalog);
_container.ComposeParts(this);
}
[Import]
public Factory _factory;
public void Run()
{
var foo = _factory.GetInstance("foo", 123);
Console.WriteLine(foo is Foo);
}
}
[Export]
public class Factory
{
private readonly ExportFactory<Foo> _fooFactory;
private readonly ExportFactory<Bar> _barFactory;
[ImportingConstructor]
public Factory(ExportFactory<Foo> fooFactory, ExportFactory<Bar> barFactory)
{
_fooFactory = fooFactory;
_barFactory = barFactory;
}
public Base GetInstance(string name, int id)
{
switch (name)
{
case "foo":
return _fooFactory.CreateExport().Value;
case "bar":
return _barFactory.CreateExport().Value;
}
throw new ArgumentException();
}
}
public class Foo : Base
{
[ImportingConstructor]
public Foo([Import("Id")] int id)
{
}
}
public class Bar : Base
{
[ImportingConstructor]
public Bar([Import("Id")] int id)
{
}
}
[InheritedExport]
public abstract class Base
{
}
source
share