提取基本接口后,缺少MissingMethodException [英] MissingMethodException after extracting base interface

查看:230
本文介绍了提取基本接口后,缺少MissingMethodException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Nuget包库中将一个接口拆分为一个更简单的基本接口(原始属性没有一个属性),并使原始对象派生自新的基本接口.

I split an interface, inside a Nuget package library, into a simpler base interface (without one property from the original), and made the original derive from the new base interface.

正在使用的应用程序中的实例化通过托管扩展框架(MEF)进行,使用具有[Import]属性的属性注入以及具有[Export(typeof(IFooConfigurations))]

Instantiation in consuming applications happens through Managed Extensibility Framework (MEF), using property injection with [Import] attributes, and implementations with [Export(typeof(IFooConfigurations))]

对于使用旧界面和实现的应用程序,这不是一个重大更改.但是在某些情况下,会加载不同的库,这些库使用旧的接口版本和实现.这样会在运行时导致MissingMethodExceptions异常,表示方法或属性(get方法)不存在-例如示例中的Configurations list属性.

This shouldn't be a breaking change, for applications using the old interface and implementation. But in some cases, different libraries are loaded, which use old interface versions and implementations. This results in MissingMethodExceptions at runtime, saying a method or property (get method) does not exist - such as the Configurations list property in the example.

:

public interface IFooConfigurations
{
    int ConfigurationsIdentifier { get; }

    IReadOnlyList<Configuration> Configurations { get; }
}

新功能:

public interface IBaseFooConfigurations
{
    // without the ConfigurationsIdentifier

    IReadOnlyList<Configuration> Configurations { get; }
}

public interface IFooConfigurations : IBaseFooConfigurations
{
    int ConfigurationsIdentifier { get; }

    // Configurations inherited from IBaseFooConfigurations
}

实施方式(未更改)

[Export(typeof(IFooConfigurations)]
public class FooConfigurations : IFooConfigurations
{
    // implementations of ConfigurationsIdentifier and Configurations 
}

用法(未更改),通过MEF解决

public class FooApplicationClass
{
    [Import]
    private IFooConfigurations ConfigurationsOwner { get; set; }
}

由于在通常的开发环境中不会发生此错误,因此很难跟踪该错误并查找可能的原因.

It is quite hard to track this error and find possible causes, because it doesn't occur in the usual development environment.

这是一个解决方案,可以使用new关键字在新版本的IFooConfigurations接口中复制现在位于基本接口中的所有旧属性和方法,同时仍然从新的属性和方法派生新的属性和方法. IBaseFooConfigurations?

Could it be a solution, to replicate all the old properties and methods, which are now in the base interface, in the new version of the IFooConfigurations interface, with the new keyword, while still deriving from the new IBaseFooConfigurations?

可能的解决方案?

public interface IFooConfigurations : IBaseFooConfigurations
{
    int ConfigurationsIdentifier { get; }

    new IReadOnlyList<Configuration> Configurations { get; }
}

似乎保留了原始接口的成员,并使用"new"关键字隐藏了继承的成员,从而解决了该问题.可能是,较旧的应用程序和库在使用原始接口时无法将继承的成员解析为原始接口的一部分.但是,明确的实现和模拟可能为此带来麻烦.仍有测试要做.

It seems like keeping the members of the original interface, hiding the inherited ones with the "new" keyword, solved the problem. Probably, older applications and libraries, working with the original interface, couldn't resolve the inherited members as parts of the original interface. However, explicit implementations and mocks can potentially be troublesome with this. There is still testing to be done.

推荐答案

从另一个接口继承的接口成员不等同于在接口本身中定义的成员.因此,将成员移动到基本接口并从其继承是一项重大更改.为了向下兼容,接口的成员本身也必须定义为"new"(在C#中).

Interface members, inherited from another interface, are not equivalent to members, which are defined in the interface itself. Therefore, moving members to a base interface and inheriting from it, is a breaking change. To be downward compatible, the members of the interface must also be defined in itself, as "new" (in C#).

我通过一个简单的测试程序确认了这一点,该程序使用原始的单个接口,拆分的DLL和拆分的和重复的新"成员引用的DLL的不同版本.因此,这不是MEF的问题.

I confirmed this with a simple test program, referencing different builds of DLLs with the original single interface, the split-up and another with the split-up and duplicate "new" members. So it is not an issue of MEF.

不幸的是,仅在运行时才构建了nuget软件包的发行版.

Unfortunately, this problem only occurs at runtime, after a release of the nuget package has already been built.

这篇关于提取基本接口后,缺少MissingMethodException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆