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

Dzy*_*ann 6 c# mef

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

我们收到此错误:

之前前提进口"MyNamespace.MyMainClass..ctor(参数='myParameter’,ContractName ='IContractInterface’)"已设置GetExportedValue不能叫.

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

var container = new CompositionContainer(catalog, true);
Run Code Online (Sandbox Code Playgroud)

的守则是:

我的简化主类代码是:(的想法是,如果没有导入的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
     }
Run Code Online (Sandbox Code Playgroud)

}

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.
        }
    }
Run Code Online (Sandbox Code Playgroud)

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

var value = export.Value;
Run Code Online (Sandbox Code Playgroud)

然而,当我调试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;
    }
}
Run Code Online (Sandbox Code Playgroud)

小智 0

由于在延迟导出时调用 export.Value 会引发异常,因此您可以了解出了什么问题。

直到那时才构建延迟导入的导出- 它只是“发现”并获取其元数据。不过,一旦您调用其值,就需要实际实例化延迟导出。

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

我认为您收到异常的最可能原因不是您的 MainClass 或 SubClass,而是您的 SubClass 中的导入。他们有导入的任何依赖项吗?这些是否得到正确解决?尝试在那里进行调查。

另外,请务必检查您捕获的异常中的 InnerExceptions !它经常会陷入整个进口链的兔子洞,直到到达实际失败的地步。