在设置先决条件导入之前,无法调用GetExportedValue

时间:2014-01-23 13:24:20

标签: c# mef

我们在 WPF 应用程序中使用 MEF

我们收到错误

  

在先决条件导入'MyNamespace.MyMainClass..ctor(Parameter =“myParameter”,ContractName =“IContractInterface”)'已设置之前,无法调用GetExportedValue。

没有使用线程,我有时会读到这个错误发生在多个线程上,但是以防万一我创建了组合容器,在true中传递了“thread safe”参数

var container = new CompositionContainer(catalog, true);

我的代码是:

我的简化主类代码是:(想法是如果IMySubClass没有导入,我将使用默认的实现,这就是我在“OmImportsSatisfied”方法上创建并满足其导入的原因。)

MyMainClass C#

[Export(typeof(IMyInterface)]
public class MyMainClass: IPartImportsSatisfiedNotification, IMyInterface
{
    [Import]
    public IContainer Container { get; private set; }

    [Import(AllowDefault = true)]
    public IMySubClass MySubClass { get; set; }

    [ImportingConstructor]
    public MyMainClass([Import(AllowDefault = true)] IContractInterface myParameter= null)
        : this()
    {
        if (myParameter!= null)
        {
            //Do Something with myParameter
        }            
    }

    public void OnImportsSatisfied()
    {
        if (MySubClass == null)
        {
            MySubClass = new MySubClass();
            Container.SatisfyImportsOnce(MySubClass);
        }

        //Some other stuff
     }

}

MySubClass C#

public class MySubClass : IPartImportsSatisfiedNotification, IMySubClass
{
    [ImportMany]
    public Lazy<IMyAttributeInterface, IMyAttributeInterfaceMetadata>[] Exports { get; set; }

    public void OnImportsSatisfied()
    {
        foreach (var export in Exports)
        {
            var value = export.Value; //Here it throws the Exception
            //Do something.
        }
    }

MySubClass中的错误在线上的OnImportSatisfied方法中抛出

var value = export.Value;

然而,当我调试MyMainClass的ImportConstructor被成功调用时, myParameter 被注入并使用。之后,OnImportsSatisfied方法被称为,我收到了错误。


我的子类中的Exports列表来自具有属性“MyExportAttribute”的其他类中的属性。我没有太多创建导出属性的经验,所以这里是代码,以防问题来自它。

导出属性

public interface IMyAttributeInterfaceMetadata
{
    string Property1 { get; }
    string Property2 { get; }
}

[MetadataAttribute]
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Class, AllowMultiple=false, Inherited=false)]
public class MyExportAttribute : ExportAttribute, IMyAttributeInterfaceMetadata
{
    string Property1 { get; }
    string Property2 { get; }

    public MyExportAttribute(string property1, string property2)
        : base(typeof(IMyAttributeInterface))
    {
        Property1 = property1;
        Property2 = property2;
    }
}

1 个答案:

答案 0 :(得分:0)

由于在懒惰的导出过程中对export.Value的调用引发了异常,因此您可以了解出了什么问题。

延迟导入的导出直到该点才被构建,而是被“发现”并获得元数据。不过,一旦您调用了它的Value,就需要实际实例化惰性输出。

到那时,它的DLL将被加载(因此,如果您在此处缺少任何依赖项,则可能会遇到异常,但这不是您的问题),并且将构造导出的类以满足MySubClass中的导入。如果导出需要其他导入(通过ImportingConstructor或单独的Import),则它将尝试解决/实例化此类,等等。

我认为您最有可能获得例外的原因不是MainClass或SubClass,而是SubClass中的导入。他们是否有要导入的依赖项?是否正确解决了这些问题?尝试在那里调查。

确保检查您捕获到的异常中的InnerExceptions !它通常沿着整个进口链的“兔子洞”走下去,直到到达实际失败的地步。