Я разделил интерфейс внутри библиотеки пакетов 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; }
}
РЕДАКТИРОВАТЬ: кажется, что сохранение элементов исходного интерфейса, скрытие унаследованных с помощью ключевого слова «новое», решило проблему. Вероятно, старые приложения и библиотеки, работающие с исходным интерфейсом, не могли разрешать унаследованные члены как части исходного интерфейса. Тем не менее, явные реализации и макеты потенциально могут быть проблематичными. Предстоит еще провести тестирование.