2012-09-10 205 views
5

更新:我应该尝试通过DI容器来处理它,还是在这里是一个错误的抽象层次?MEF和ABSTRACT FACTORY

我想使用MEF(.NET 4.5)实现ABSTRACT FACTORY。

它不工作对我来说...

的组成保持不变。由于以下错误,更改被拒绝:

组合物产生单一组合错误。根源在下面提供。查看CompositionException.Errors属性以获取更多详细信息。

1)出口没有发现匹配的约束:

ContractName Mef3.Factory

RequiredTypeIdentity Mef3.Factory ,导致:无法设置进口“Mef3.Program._factory(ContractName =“MEF3。工厂“)'部分'Mef3.Program'。

元素:Mef3.Program._factory(ContractName = “Mef3.Factory”) - > Mef3.Program

是它做它在MEF的正确方法? 如何将id转发到Foo/Bar ctors?

代码:

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 
{ 
} 

回答

1

问题看起来你的[导入( “ID”)在Foo和Bar引起的。没有合同名称为“Id”的导出。一般来说,MEF不允许你在运行时传入进口,你需要能够在组合时满足整个图形,否则它将无法工作。如果您想使用MEF来完成这个特定场景,您应该删除Foo和Bar上的ImportingConstructor,并在Base类上添加一个SetId方法,并让您的工厂在调用GetInstance时调用它。

+0

谢谢。我删除了Foo/Bar ctor参数。它引发同样的异常。 –

+0

使用属性注入为id看起来很奇怪,因为它不是可选的。你认为这种情况不适合DI模式吗?是MEF唯一的问题吗?我应该使用其他DI容器还是DI只是一个错误的抽象级别? –

+0

有人试过这段代码吗?我是唯一抛出异常的人吗? –