Я разделил интерфейс внутри библиотеки пакета Nuget на более простой базовый интерфейс (без одного свойства из оригинала) и сделал исходный код производным от нового базового интерфейса.
Инстанцирование в потребляющих приложениях происходит через Managed Extensibility Framework (MEF), используя внедрение свойств с атрибутами [Import]
и реализации с [Export(typeof(IFooConfigurations))]
Это не должно быть серьезным изменением для приложений, использующих старый интерфейс и реализацию. Но в некоторых случаях загружаются разные библиотеки, которые используют старые версии интерфейса и реализации. Это приводит к MissingMethodExceptions во время выполнения, говоря, что метод или свойство (метод get) не существует - например, свойство списка Configurations
в примере.
Старый
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; }
}
Довольно сложно отследить эту ошибку и найти возможные причины, потому что она не возникает в обычной среде разработки.
Может ли это быть решением, реплицировать все старые свойства и методы, которые теперь находятся в базовом интерфейсе, в новую версию интерфейса IFooConfigurations
с ключевым словом new
, но все еще производным от нового IBaseFooConfigurations
Возможное решение?
public interface IFooConfigurations : IBaseFooConfigurations
{
int ConfigurationsIdentifier { get; }
new IReadOnlyList<Configuration> Configurations { get; }
}
РЕДАКТИРОВАТЬ: Похоже, что сохранение членов исходного интерфейса, скрывая унаследованные с ключевым словом "new", решило проблему. Возможно, старые приложения и библиотеки, работающие с оригинальным интерфейсом, не могли разрешить унаследованные элементы как части оригинального интерфейса. Тем не менее, явные реализации и макеты могут быть неприятны с этим. Проверка еще не завершена.