MissingMethodException after extracting base interface

£可爱£侵袭症+ 提交于 2019-12-12 23:12:15

问题


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.

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

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.

Old:

public interface IFooConfigurations
{
    int ConfigurationsIdentifier { get; }

    IReadOnlyList<Configuration> Configurations { get; }
}

New:

public interface IBaseFooConfigurations
{
    // without the ConfigurationsIdentifier

    IReadOnlyList<Configuration> Configurations { get; }
}

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

    // Configurations inherited from IBaseFooConfigurations
}

Implementation (not changed)

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

Usage (not changed), resolved through 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.

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?

Possible solution?

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

    new IReadOnlyList<Configuration> Configurations { get; }
}

EDIT: 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.


回答1:


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#).

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.

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



来源:https://stackoverflow.com/questions/55061714/missingmethodexception-after-extracting-base-interface

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!