Почему я не могу создать подобие прокси, когда абстрактный класс не раскрывает все аргументы конструктора?

Я пользуюсь библиотекой SemanticComparison от Ploeh с большим успехом - за исключением случаев, когда у меня есть абстрактный класс, который не раскрывает все аргументы конструктора.

Вот исключение, которое я получаю -

Ploeh.SemanticComparison.ProxyCreationException : The proxy of Foo could not be created using the same semantic heuristics as the default semantic comparison. In order to create proxies of types with non-parameterless constructor the values from the source constructor must be compatible to the parameters of the destination constructor.
  ----> System.InvalidOperationException : Operation is not valid due to the current state of the object.

Вот самый простой пример, который я мог придумать -

// this fails with the aforementioned exception
_fixture.Create<Foo>().AsSource().OfLikeness<Foo>().CreateProxy();

public class Foo : Bar
{
    public Foo(int age)
        : base(age)
    {           
    }
}

public abstract class Bar
{
    private readonly int _age;

    protected Bar(int age)
    {
        _age = age;
    }
}

Однако, если я добавлю public int NotAge { get; set; } абстрагировать класс Barтогда все хорошо. Я действительно считаю это неоптимальным решением, потому что я не хочу выставлять собственность age, Это просто используется для расчета других вещей.

Как я могу решить эту проблему, не выставляя свойства только ради тестирования. Может быть, есть еще одна библиотека, которая может достичь того же эффекта без этой проблемы?

1 ответ

Решение

Эта ошибка возникает, когда возникла проблема при извлечении свойств целевого класса и сопоставлении с конструкторами типа источника, хотя ошибка читается так, как если бы отображались только конструкторы.

В вашем случае внутреннее исключение связано с отсутствием открытых свойств ни в одном классе. Я почти уверен, что твое исправление просто перенаправляет отображение в твою фиктивную собственность.

Вы можете исправить это с public int age { get { return _age; } } на базовом классе - в этом примере мало вреда.

Обычный аварийный люк для такого рода проблем заключается в использовании InternalVisibleTo но библиотека в настоящее время использует только BindingFlags.Public при отображении типов, чтобы он не видел внутреннее свойство, созданное для этой цели.

Я смог получить прокси для создания путем настройки источника для использования BindingFlags.NonPublic в дополнение к BindingFlags.Public но я не уверен, что это разумный подход.

Другие вопросы по тегам